From c4898b7e980035c3978876f5d434ca61b58715de Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sun, 18 Apr 2021 14:13:53 +1000 Subject: [PATCH 001/154] Plumb in filtering on ingress class name --- main.go | 1 + pkg/apis/externaldns/types.go | 3 +++ source/ingress.go | 32 +++++++++++++++++++++++++++++++- source/store.go | 3 ++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 5843a583f9..b10c3372a8 100644 --- a/main.go +++ b/main.go @@ -104,6 +104,7 @@ func main() { Namespace: cfg.Namespace, AnnotationFilter: cfg.AnnotationFilter, LabelFilter: cfg.LabelFilter, + IngressClassNameFilter: cfg.IngressClassNameFilter, FQDNTemplate: cfg.FQDNTemplate, CombineFQDNAndAnnotation: cfg.CombineFQDNAndAnnotation, IgnoreHostnameAnnotation: cfg.IgnoreHostnameAnnotation, diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 89e053b865..e9153ab7ca 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -53,6 +53,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string + IngressClassNameFilter []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -186,6 +187,7 @@ var defaultConfig = &Config{ Namespace: "", AnnotationFilter: "", LabelFilter: "", + IngressClassNameFilter: nil, FQDNTemplate: "", CombineFQDNAndAnnotation: false, IgnoreHostnameAnnotation: false, @@ -362,6 +364,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter) + app.Flag("ingress-class-filter", "Filter ingresses to just these ingress class(es)").StringsVar(&cfg.IngressClassNameFilter) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation) app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when using fqdn-template is set (optional, default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation) diff --git a/source/ingress.go b/source/ingress.go index e81f524d14..01b9873004 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -54,6 +54,7 @@ type ingressSource struct { client kubernetes.Interface namespace string annotationFilter string + ingressClassNameFilter []string fqdnTemplate *template.Template combineFQDNAnnotation bool ignoreHostnameAnnotation bool @@ -63,7 +64,7 @@ type ingressSource struct { } // NewIngressSource creates a new ingressSource with the given config. -func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool) (Source, error) { +func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool, ingressClassNameFilter []string) (Source, error) { tmpl, err := parseTemplate(fqdnTemplate) if err != nil { return nil, err @@ -94,6 +95,7 @@ func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilt client: kubeClient, namespace: namespace, annotationFilter: annotationFilter, + ingressClassNameFilter: ingressClassNameFilter, fqdnTemplate: tmpl, combineFQDNAnnotation: combineFqdnAnnotation, ignoreHostnameAnnotation: ignoreHostnameAnnotation, @@ -116,6 +118,11 @@ func (sc *ingressSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e return nil, err } + ingresses, err = sc.filterByIngressClass(ingresses) + if err != nil { + return nil, err + } + endpoints := []*endpoint.Endpoint{} for _, ing := range ingresses { @@ -210,6 +217,29 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] return filteredList, nil } +// filterByIngressClass filters a list of ingresses based on a required ingress +// class +func (sc *ingressSource) filterByIngressClass(ingresses []*v1beta1.Ingress) ([]*v1beta1.Ingress, error) { + // if no class is specified then there's nothing to do + if sc.ingressClassNameFilter == nil { + return ingresses, nil + } + + filteredList := []*v1beta1.Ingress{} + + for _, ingress := range ingresses { + for _, nameFilter := range sc.ingressClassNameFilter { + // include ingress if its annotations match the selector + if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { + filteredList = append(filteredList, ingress) + break + } + } + } + + return filteredList, nil +} + func (sc *ingressSource) setResourceLabel(ingress *networkv1.Ingress, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingress/%s/%s", ingress.Namespace, ingress.Name) diff --git a/source/store.go b/source/store.go index 3b83722556..5cb2d47bfe 100644 --- a/source/store.go +++ b/source/store.go @@ -43,6 +43,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string + IngressClassNameFilter []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -189,7 +190,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err if err != nil { return nil, err } - return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec) + return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec, cfg.IngressClassNameFilter) case "pod": client, err := p.KubeClient() if err != nil { From 115e2501af1e9b4dc3a37bbc08a648e9031e24c5 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sun, 18 Apr 2021 16:27:01 +1000 Subject: [PATCH 002/154] Add ingressClassNameFilter testing --- source/ingress_test.go | 47 +++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/source/ingress_test.go b/source/ingress_test.go index c9d35494c8..4b22be0919 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -63,6 +63,7 @@ func (suite *IngressSuite) SetupTest() { false, false, false, + []string{}, ) suite.NoError(err, "should initialize ingress source") } @@ -144,6 +145,7 @@ func TestNewIngressSource(t *testing.T) { false, false, false, + []string{}, ) if ti.expectError { assert.Error(t, err) @@ -358,6 +360,7 @@ func testIngressEndpoints(t *testing.T) { ignoreHostnameAnnotation bool ignoreIngressTLSSpec bool ignoreIngressRulesSpec bool + ingressClassNameFilter []string }{ { title: "no ingress", @@ -1169,6 +1172,33 @@ func testIngressEndpoints(t *testing.T) { }, }, }, + { + title: "ingressClassName filtering", + targetNamespace: "", + ingressClassNameFilter: []string{"public"}, + ingressItems: []fakeIngress{ + { + name: "fake-public", + namespace: namespace, + tlsdnsnames: [][]string{{"example.org"}}, + ips: []string{"1.2.3.4"}, + ingressClassName: "public", + }, + { + name: "fake-internal", + namespace: namespace, + tlsdnsnames: [][]string{{"int.example.org"}}, + ips: []string{"2.3.4.5"}, + ingressClassName: "internal", + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "example.org", + Targets: endpoint.Targets{"1.2.3.4"}, + }, + }, + }, } { ti := ti t.Run(ti.title, func(t *testing.T) { @@ -1189,6 +1219,7 @@ func testIngressEndpoints(t *testing.T) { ti.ignoreHostnameAnnotation, ti.ignoreIngressTLSSpec, ti.ignoreIngressRulesSpec, + ti.ingressClassNameFilter, ) // Informer cache has all of the ingresses. Retrieve and validate their endpoints. res, err := source.Endpoints(context.Background()) @@ -1204,13 +1235,14 @@ func testIngressEndpoints(t *testing.T) { // ingress specific helper functions type fakeIngress struct { - dnsnames []string - tlsdnsnames [][]string - ips []string - hostnames []string - namespace string - name string - annotations map[string]string + dnsnames []string + tlsdnsnames [][]string + ips []string + hostnames []string + namespace string + name string + annotations map[string]string + ingressClassName string } func (ing fakeIngress) Ingress() *networkv1.Ingress { @@ -1222,6 +1254,7 @@ func (ing fakeIngress) Ingress() *networkv1.Ingress { }, Spec: networkv1.IngressSpec{ Rules: []networkv1.IngressRule{}, + IngressClassName: &ing.ingressClassName, }, Status: networkv1.IngressStatus{ LoadBalancer: v1.LoadBalancerStatus{ From c823eba1392ecd493c5e33f598799a41d657ddd7 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 14:34:34 +1000 Subject: [PATCH 003/154] ingress source: update code for networkv1 --- source/ingress.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index 01b9873004..184ce299c1 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -219,13 +219,13 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] // filterByIngressClass filters a list of ingresses based on a required ingress // class -func (sc *ingressSource) filterByIngressClass(ingresses []*v1beta1.Ingress) ([]*v1beta1.Ingress, error) { +func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([]*networkv1.Ingress, error) { // if no class is specified then there's nothing to do if sc.ingressClassNameFilter == nil { return ingresses, nil } - filteredList := []*v1beta1.Ingress{} + filteredList := []*networkv1.Ingress{} for _, ingress := range ingresses { for _, nameFilter := range sc.ingressClassNameFilter { From 0b6c67fe56d5dee40cafa4d2922cb80716477a07 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 14:34:49 +1000 Subject: [PATCH 004/154] cli args: rename ingress-class-filter to ingress-classes --- pkg/apis/externaldns/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index e9153ab7ca..4210f1df8a 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -364,7 +364,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter) - app.Flag("ingress-class-filter", "Filter ingresses to just these ingress class(es)").StringsVar(&cfg.IngressClassNameFilter) + app.Flag("ingress-classes", "Restrict ingress source to just these classes (defaults to any class)").StringsVar(&cfg.IngressClassNameFilter) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation) app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when using fqdn-template is set (optional, default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation) From da71b3fff860ee65e71ca5d89196e821a775ca43 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 15:13:45 +1000 Subject: [PATCH 005/154] ingress source: improve class name filtering and logging --- source/ingress.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index 184ce299c1..e3aa63ff23 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -220,7 +220,7 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] // filterByIngressClass filters a list of ingresses based on a required ingress // class func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([]*networkv1.Ingress, error) { - // if no class is specified then there's nothing to do + // if no class filter is specified then there's nothing to do if sc.ingressClassNameFilter == nil { return ingresses, nil } @@ -228,13 +228,22 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ filteredList := []*networkv1.Ingress{} for _, ingress := range ingresses { + // we have a filter class but this ingress doesn't have its class set + if ingress.Spec.IngressClassName == nil { + log.Debugf("Ignoring ingress %s/%s because ingressClassName is not set", ingress.Namespace, ingress.Name) + } + + var matched = false; for _, nameFilter := range sc.ingressClassNameFilter { - // include ingress if its annotations match the selector - if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { + if nameFilter == *ingress.Spec.IngressClassName { filteredList = append(filteredList, ingress) + matched = true; break } } + if matched == false { + log.Debugf("Ignoring ingress %s/%s because ingressClassName '%s' is not in specified list", ingress.Namespace, ingress.Name, *ingress.Spec.IngressClassName) + } } return filteredList, nil From 8da6f99857dc405bc4a0c50a7c416a86e421ea36 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 15:21:37 +1000 Subject: [PATCH 006/154] Rename ingressClassNameFilter to ingressClassNames ...and update the help text to specify use more clearly --- main.go | 2 +- pkg/apis/externaldns/types.go | 6 +++--- source/ingress.go | 10 +++++----- source/ingress_test.go | 2 +- source/store.go | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index b10c3372a8..bc26e0f4d7 100644 --- a/main.go +++ b/main.go @@ -104,7 +104,7 @@ func main() { Namespace: cfg.Namespace, AnnotationFilter: cfg.AnnotationFilter, LabelFilter: cfg.LabelFilter, - IngressClassNameFilter: cfg.IngressClassNameFilter, + IngressClassNames: cfg.IngressClassNames, FQDNTemplate: cfg.FQDNTemplate, CombineFQDNAndAnnotation: cfg.CombineFQDNAndAnnotation, IgnoreHostnameAnnotation: cfg.IgnoreHostnameAnnotation, diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 4210f1df8a..f9df5d9333 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -53,7 +53,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string - IngressClassNameFilter []string + IngressClassNames []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -187,7 +187,7 @@ var defaultConfig = &Config{ Namespace: "", AnnotationFilter: "", LabelFilter: "", - IngressClassNameFilter: nil, + IngressClassNames: nil, FQDNTemplate: "", CombineFQDNAndAnnotation: false, IgnoreHostnameAnnotation: false, @@ -364,7 +364,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter) - app.Flag("ingress-classes", "Restrict ingress source to just these classes (defaults to any class)").StringsVar(&cfg.IngressClassNameFilter) + app.Flag("ingress-class", "Require an ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation) app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when using fqdn-template is set (optional, default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation) diff --git a/source/ingress.go b/source/ingress.go index e3aa63ff23..0f27d6bb8a 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -54,7 +54,7 @@ type ingressSource struct { client kubernetes.Interface namespace string annotationFilter string - ingressClassNameFilter []string + ingressClassNames []string fqdnTemplate *template.Template combineFQDNAnnotation bool ignoreHostnameAnnotation bool @@ -64,7 +64,7 @@ type ingressSource struct { } // NewIngressSource creates a new ingressSource with the given config. -func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool, ingressClassNameFilter []string) (Source, error) { +func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool, ingressClassNames []string) (Source, error) { tmpl, err := parseTemplate(fqdnTemplate) if err != nil { return nil, err @@ -95,7 +95,7 @@ func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilt client: kubeClient, namespace: namespace, annotationFilter: annotationFilter, - ingressClassNameFilter: ingressClassNameFilter, + ingressClassNames: ingressClassNames, fqdnTemplate: tmpl, combineFQDNAnnotation: combineFqdnAnnotation, ignoreHostnameAnnotation: ignoreHostnameAnnotation, @@ -221,7 +221,7 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] // class func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([]*networkv1.Ingress, error) { // if no class filter is specified then there's nothing to do - if sc.ingressClassNameFilter == nil { + if sc.ingressClassNames == nil { return ingresses, nil } @@ -234,7 +234,7 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ } var matched = false; - for _, nameFilter := range sc.ingressClassNameFilter { + for _, nameFilter := range sc.ingressClassNames { if nameFilter == *ingress.Spec.IngressClassName { filteredList = append(filteredList, ingress) matched = true; diff --git a/source/ingress_test.go b/source/ingress_test.go index 4b22be0919..804f35fa97 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -360,7 +360,7 @@ func testIngressEndpoints(t *testing.T) { ignoreHostnameAnnotation bool ignoreIngressTLSSpec bool ignoreIngressRulesSpec bool - ingressClassNameFilter []string + ingressClassNames []string }{ { title: "no ingress", diff --git a/source/store.go b/source/store.go index 5cb2d47bfe..9e5743ffb9 100644 --- a/source/store.go +++ b/source/store.go @@ -43,7 +43,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string - IngressClassNameFilter []string + IngressClassNames []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -190,7 +190,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err if err != nil { return nil, err } - return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec, cfg.IngressClassNameFilter) + return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec, cfg.IngressClassNames) case "pod": client, err := p.KubeClient() if err != nil { From ac0c4be36ad8a308287e178f090c66cf15c64ecc Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 15:23:48 +1000 Subject: [PATCH 007/154] Update tests for ingress class filtering --- source/ingress_test.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/source/ingress_test.go b/source/ingress_test.go index 804f35fa97..9f1590a4c0 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -1175,7 +1175,7 @@ func testIngressEndpoints(t *testing.T) { { title: "ingressClassName filtering", targetNamespace: "", - ingressClassNameFilter: []string{"public"}, + ingressClassNames: []string{"public", "dmz"}, ingressItems: []fakeIngress{ { name: "fake-public", @@ -1191,12 +1191,23 @@ func testIngressEndpoints(t *testing.T) { ips: []string{"2.3.4.5"}, ingressClassName: "internal", }, + { + name: "fake-dmz", + namespace: namespace, + tlsdnsnames: [][]string{{"dmz.example.org"}}, + ips: []string{"3.4.5.6"}, + ingressClassName: "dmz", + }, }, expected: []*endpoint.Endpoint{ { DNSName: "example.org", Targets: endpoint.Targets{"1.2.3.4"}, }, + { + DNSName: "dmz.example.org", + Targets: endpoint.Targets{"3.4.5.6"}, + }, }, }, } { @@ -1219,7 +1230,7 @@ func testIngressEndpoints(t *testing.T) { ti.ignoreHostnameAnnotation, ti.ignoreIngressTLSSpec, ti.ignoreIngressRulesSpec, - ti.ingressClassNameFilter, + ti.ingressClassNames, ) // Informer cache has all of the ingresses. Retrieve and validate their endpoints. res, err := source.Endpoints(context.Background()) From 71a672fe720c5ca99e7b019e086ceb563ec52560 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:02:33 +1000 Subject: [PATCH 008/154] ingress source: check for duplicate classname configs we don't want to get incompatible restrictions by letting someone set "--ingress-class" and --annotation-filter="kubernetes.io/ingress.class" at the same time --- source/ingress.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/ingress.go b/source/ingress.go index 0f27d6bb8a..bb0bf2961e 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -18,6 +18,7 @@ package source import ( "context" + "errors" "fmt" "sort" "strings" @@ -70,6 +71,21 @@ func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilt return nil, err } + // ensure that ingress class is only set in either the ingressClassNames or + // annotationFilter but not both + if ingressClassNames != nil && annotationFilter != "" { + selector, err := getLabelSelector(annotationFilter) + if err != nil { + return nil, err + } + + requirements, _ := selector.Requirements() + for _, requirement := range requirements { + if requirement.Key() == "kubernetes.io/ingress.class" { + return nil, errors.New("--ingress-class is mutually exclusive with kubernetes.io/ingress.class annotation") + } + } + } // Use shared informer to listen for add/update/delete of ingresses in the specified namespace. // Set resync period to 0, to prevent processing when nothing has changed. informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace)) From 901effbca5207e2f8e49d6e2e066be9e8470b0be Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:32:40 +1000 Subject: [PATCH 009/154] ingress source: ingressClassNames now feed into annotation filter --- source/ingress.go | 27 +++++++++++++++++++-------- source/ingress_test.go | 13 +++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index bb0bf2961e..58fb119be2 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -27,6 +27,7 @@ import ( log "github.com/sirupsen/logrus" networkv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/wait" kubeinformers "k8s.io/client-go/informers" netinformers "k8s.io/client-go/informers/networking/v1" @@ -241,24 +242,34 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ return ingresses, nil } + classNameReq, err := labels.NewRequirement("kubernetes.io/ingress.class", selection.In, sc.ingressClassNames) + if err != nil { + return nil, errors.New("Failed to create selector requirement from ingress class names") + } + + selector := labels.NewSelector() + selector = selector.Add(*classNameReq) + filteredList := []*networkv1.Ingress{} for _, ingress := range ingresses { - // we have a filter class but this ingress doesn't have its class set - if ingress.Spec.IngressClassName == nil { - log.Debugf("Ignoring ingress %s/%s because ingressClassName is not set", ingress.Namespace, ingress.Name) - } - var matched = false; + for _, nameFilter := range sc.ingressClassNames { - if nameFilter == *ingress.Spec.IngressClassName { - filteredList = append(filteredList, ingress) + if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { + matched = true; + } else if matchLabelSelector(selector, ingress.Annotations) { matched = true; + } + + if matched == true { + filteredList = append(filteredList, ingress) break } } + if matched == false { - log.Debugf("Ignoring ingress %s/%s because ingressClassName '%s' is not in specified list", ingress.Namespace, ingress.Name, *ingress.Spec.IngressClassName) + log.Debugf("Discarding ingress %s/%s because it does not match required ingress classes %v", ingress.Namespace, ingress.Name, sc.ingressClassNames) } } diff --git a/source/ingress_test.go b/source/ingress_test.go index 9f1590a4c0..9cf60d9630 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -1198,6 +1198,15 @@ func testIngressEndpoints(t *testing.T) { ips: []string{"3.4.5.6"}, ingressClassName: "dmz", }, + { + name: "annotated-dmz", + namespace: namespace, + tlsdnsnames: [][]string{{"annodmz.example.org"}}, + ips: []string{"4.5.6.7"}, + annotations: map[string]string{ + "kubernetes.io/ingress.class": "dmz", + }, + }, }, expected: []*endpoint.Endpoint{ { @@ -1208,6 +1217,10 @@ func testIngressEndpoints(t *testing.T) { DNSName: "dmz.example.org", Targets: endpoint.Targets{"3.4.5.6"}, }, + { + DNSName: "annodmz.example.org", + Targets: endpoint.Targets{"4.5.6.7"}, + }, }, }, } { From 807e213590b01e01e52060f564e63fbb8ce7bba5 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:37:02 +1000 Subject: [PATCH 010/154] docs: add info about new --ingress-class --- docs/faq.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 67662a782b..2ce8ab48aa 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -254,13 +254,16 @@ Sometimes you need to run an internal and an external dns service. The internal one should provision hostnames used on the internal network (perhaps inside a VPC), and the external one to expose DNS to the internet. -To do this with ExternalDNS you can use the `--annotation-filter` to specifically tie an instance of ExternalDNS to +To do this with ExternalDNS you can use the `--ingress-class` to specifically tie an instance of ExternalDNS to an instance of a ingress controller. Let's assume you have two ingress controllers `nginx-internal` and `nginx-external` -then you can start two ExternalDNS providers one with `--annotation-filter=kubernetes.io/ingress.class in (nginx-internal)` -and one with `--annotation-filter=kubernetes.io/ingress.class in (nginx-external)`. +then you can start two ExternalDNS providers one with `--ingress-class=nginx-internal` and one with `--ingress-class=nginx-external`. -If you need to search for multiple values of said annotation, you can provide a comma separated list, like so: -`--annotation-filter=kubernetes.io/ingress.class in (nginx-internal, alb-ingress-internal)`. +If you need to search for multiple ingress classes, you can specify the argument multiple times, like so: +`--ingress-class=nginx-internal --ingress-class=alb-ingress-internal`. + +The `--ingress-class` argument will check both the ingressClassName field as well as the deprecated `kubernetes.io/ingress.class` annotation. + +Note: the `--ingress-class` argument cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. Beware when using multiple sources, e.g. `--source=service --source=ingress`, `--annotation-filter` will filter every given source objects. If you need to filter only one specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. From 8ec342a1c6ac3c95540ee87c4f3c94afe9f15635 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:41:39 +1000 Subject: [PATCH 011/154] docs: format ingressClassName as inline code --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 2ce8ab48aa..2ce3ed4810 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -261,7 +261,7 @@ then you can start two ExternalDNS providers one with `--ingress-class=nginx-int If you need to search for multiple ingress classes, you can specify the argument multiple times, like so: `--ingress-class=nginx-internal --ingress-class=alb-ingress-internal`. -The `--ingress-class` argument will check both the ingressClassName field as well as the deprecated `kubernetes.io/ingress.class` annotation. +The `--ingress-class` argument will check both the `ingressClassName` field as well as the deprecated `kubernetes.io/ingress.class` annotation. Note: the `--ingress-class` argument cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. From a24217a720278d84eee2d9881e952f87a3d307e1 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:49:51 +1000 Subject: [PATCH 012/154] ingress source: use shorthand bool comparison --- source/ingress.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index 58fb119be2..b92e4475d9 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -262,13 +262,13 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ matched = true; } - if matched == true { + if matched { filteredList = append(filteredList, ingress) break } } - if matched == false { + if !matched { log.Debugf("Discarding ingress %s/%s because it does not match required ingress classes %v", ingress.Namespace, ingress.Name, sc.ingressClassNames) } } From 0aa3d55450cf06161583156ff63b61c73473fff2 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:50:35 +1000 Subject: [PATCH 013/154] ingress source: pass back err when requirement fails --- source/ingress.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ingress.go b/source/ingress.go index b92e4475d9..371ba9248d 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -244,7 +244,7 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ classNameReq, err := labels.NewRequirement("kubernetes.io/ingress.class", selection.In, sc.ingressClassNames) if err != nil { - return nil, errors.New("Failed to create selector requirement from ingress class names") + return nil, err } selector := labels.NewSelector() From 6c4a450b254bdfc23f4243f6bef657e406ecb028 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 16:54:42 +1000 Subject: [PATCH 014/154] gofmt simplify new ingress-class changes --- pkg/apis/externaldns/types.go | 2 +- source/ingress.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index f9df5d9333..a59e356be1 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -364,7 +364,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) app.Flag("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter) - app.Flag("ingress-class", "Require an ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames) + app.Flag("ingress-class", "Require an ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames) app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate) app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation) app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when using fqdn-template is set (optional, default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation) diff --git a/source/ingress.go b/source/ingress.go index 371ba9248d..33a16c3b84 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -56,7 +56,7 @@ type ingressSource struct { client kubernetes.Interface namespace string annotationFilter string - ingressClassNames []string + ingressClassNames []string fqdnTemplate *template.Template combineFQDNAnnotation bool ignoreHostnameAnnotation bool @@ -135,7 +135,7 @@ func (sc *ingressSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e return nil, err } - ingresses, err = sc.filterByIngressClass(ingresses) + ingresses, err = sc.filterByIngressClass(ingresses) if err != nil { return nil, err } @@ -253,13 +253,13 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ filteredList := []*networkv1.Ingress{} for _, ingress := range ingresses { - var matched = false; + var matched = false for _, nameFilter := range sc.ingressClassNames { if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { - matched = true; + matched = true } else if matchLabelSelector(selector, ingress.Annotations) { - matched = true; + matched = true } if matched { From 31bc5bb0778d9dd06ab93b0c26b08fd50eb5ddba Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sat, 2 Oct 2021 17:08:54 +1000 Subject: [PATCH 015/154] ingress source: fix broken NewIngressSource test and add an extra one for the mutual exclusivity of ingressClassNames and ingress.class annotationFilters --- source/ingress_test.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/ingress_test.go b/source/ingress_test.go index 9cf60d9630..f79a7b2220 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -100,6 +100,7 @@ func TestNewIngressSource(t *testing.T) { fqdnTemplate string combineFQDNAndAnnotation bool expectError bool + ingressClassNames []string }{ { title: "invalid template", @@ -131,6 +132,17 @@ func TestNewIngressSource(t *testing.T) { expectError: false, annotationFilter: "kubernetes.io/ingress.class=nginx", }, + { + title: "non-empty ingress class name list", + expectError: false, + ingressClassNames: []string{"internal", "external"}, + }, + { + title: "ingress class name and annotation filter jointly specified", + expectError: true, + ingressClassNames: []string{"internal", "external"}, + annotationFilter: "kubernetes.io/ingress.class=nginx", + }, } { ti := ti t.Run(ti.title, func(t *testing.T) { @@ -145,7 +157,7 @@ func TestNewIngressSource(t *testing.T) { false, false, false, - []string{}, + ti.ingressClassNames, ) if ti.expectError { assert.Error(t, err) From 99c10f56c634ffcaaa6a4f775d156fbdd81222c9 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Mon, 14 Feb 2022 16:37:28 +1100 Subject: [PATCH 016/154] ingress source: improve mutual exclusive error message --- source/ingress.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ingress.go b/source/ingress.go index 0057392106..56833e15c1 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -83,7 +83,7 @@ func NewIngressSource(ctx context.Context, kubeClient kubernetes.Interface, name requirements, _ := selector.Requirements() for _, requirement := range requirements { if requirement.Key() == "kubernetes.io/ingress.class" { - return nil, errors.New("--ingress-class is mutually exclusive with kubernetes.io/ingress.class annotation") + return nil, errors.New("--ingress-class is mutually exclusive with the kubernetes.io/ingress.class annotation filter") } } } From 15f27aafd3517531978685a3039a054df2c0b985 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Mon, 14 Feb 2022 16:48:56 +1100 Subject: [PATCH 017/154] faq: extend notes about annotation filter risks --- docs/faq.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 9cda9c59fe..10a36422f5 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -269,10 +269,12 @@ The `--ingress-class` argument will check both the `ingressClassName` field as w Note: the `--ingress-class` argument cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. -Beware when using multiple sources, e.g. `--source=service --source=ingress`, `--annotation-filter` will filter every given source objects. -If you need to filter only one specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. +If you use annotations to indicate different ingress classes in your cluster, you can instead use an `--annotation-filter` argument to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. -**Note:** Filtering based on annotation means that the external-dns controller will receive all resources of that kind and then filter on the client-side. +However, beware when using annotation filters with multiple sources, e.g. `--source=service --source=ingress`, since `--annotation-filter` will filter every given source objects. +If you need to use annotation filters against a specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. + +**Note:** Filtering based on annotation or ingress class name means that the external-dns controller will receive all resources of that kind and then filter on the client-side. In larger clusters with many resources which change frequently this can cause performance issues. If only some resources need to be managed by an instance of external-dns then label filtering can be used instead of annotation filtering. This means that only those resources which match the selector specified in `--label-filter` will be passed to the controller. From f76382a5adb1e92e821978b6b9ee298cb9514ac0 Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Mon, 14 Feb 2022 16:57:01 +1100 Subject: [PATCH 018/154] docs: update public-private-route53 example for ingress-class filtering --- docs/tutorials/public-private-route53.md | 32 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index 764a7e7474..b8110ecbd2 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -213,7 +213,7 @@ spec: Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. -In ExternalDNS containers args, make sure to specify `annotation-filter` and `aws-zone-type`: +In ExternalDNS containers args, make sure to specify `aws-zone-type` and either `ingress-class` or `annotation-filter` (depending on whether your cluster makes use of `ingressClassName`): ```yaml apiVersion: apps/v1beta2 @@ -241,7 +241,9 @@ spec: - --provider=aws - --registry=txt - --txt-owner-id=external-dns - - --annotation-filter=kubernetes.io/ingress.class in (external-ingress) + - --ingress-class=external-ingress + # ... or, if you use annotations for ingress classes + # - --annotation-filter=kubernetes.io/ingress.class in (external-ingress) - --aws-zone-type=public image: k8s.gcr.io/external-dns/external-dns:v0.7.6 name: external-dns-public @@ -251,7 +253,7 @@ spec: Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. -In ExternalDNS containers args, make sure to specify `annotation-filter` and `aws-zone-type`: +In ExternalDNS containers args, make sure to specify `aws-zone-type` and either `ingress-class` or `annotation-filter` (depending on whether your cluster makes use of `ingressClassName`): ```yaml apiVersion: apps/v1beta2 @@ -279,7 +281,9 @@ spec: - --provider=aws - --registry=txt - --txt-owner-id=dev.k8s.nexus - - --annotation-filter=kubernetes.io/ingress.class in (internal-ingress) + - --ingress-class=internal-ingress + # ... or, if you use annotations for ingress classes + # - --annotation-filter=kubernetes.io/ingress.class in (internal-ingress) - --aws-zone-type=private image: k8s.gcr.io/external-dns/external-dns:v0.7.6 name: external-dns-private @@ -287,20 +291,23 @@ spec: ## Create application Service definitions -For this setup to work, you've to create two Service definitions for your application. +For this setup to work, you need to create two Ingress definitions for your application. -At first, create public Service definition: +At first, create public Ingress definition (make sure to un-comment either the `annotations` or `ingressClassName` lines): ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - annotations: - kubernetes.io/ingress.class: "external-ingress" + # uncomment if you use annotations for ingress classes + # annotations: + # kubernetes.io/ingress.class: "external-ingress" labels: app: app name: app-public spec: + # uncomment if you use ingressClassName + # ingressClassName: external-ingress rules: - host: app.domain.com http: @@ -310,18 +317,21 @@ spec: servicePort: 80 ``` -Then create private Service definition: +Then create private Ingress definition (again, make sure to un-comment either the `annotations` or `ingressClassName` lines): ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - annotations: - kubernetes.io/ingress.class: "internal-ingress" + # uncomment if you use annotations for ingress classes + # annotations: + # kubernetes.io/ingress.class: "internal-ingress" labels: app: app name: app-private spec: + # uncomment if you use ingressClassName + # ingressClassName: internal-ingress rules: - host: app.domain.com http: From 07dc39abc7a7ae4e7625e08921922f3d8fa05d9f Mon Sep 17 00:00:00 2001 From: Ole Markus With Date: Sun, 20 Nov 2022 15:40:00 +0100 Subject: [PATCH 019/154] If controller error propagates all the way out, bail execution --- controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/controller.go b/controller/controller.go index 528d870faa..742c6f2c7a 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -292,7 +292,7 @@ func (c *Controller) Run(ctx context.Context) { for { if c.ShouldRunOnce(time.Now()) { if err := c.RunOnce(ctx); err != nil { - log.Error(err) + log.Fatal(err) } } select { From b99289d0c9d0823dd7e9d8635ad70889bf2ada9d Mon Sep 17 00:00:00 2001 From: gugdewescale Date: Tue, 3 Jan 2023 08:57:41 +0100 Subject: [PATCH 020/154] fix: scaleway documentation, remove SCW_DEFAULT_ORGANIZATION_ID --- docs/tutorials/scaleway.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/tutorials/scaleway.md b/docs/tutorials/scaleway.md index b3b7ca88ac..7b74918c4c 100644 --- a/docs/tutorials/scaleway.md +++ b/docs/tutorials/scaleway.md @@ -19,12 +19,10 @@ In this example we will use `example.com` as an example. To use ExternalDNS with Scaleway DNS, you need to create an API token (composed of the Access Key and the Secret Key). You can either use existing ones or you can create a new token, as explained in [How to generate an API token](https://www.scaleway.com/en/docs/generate-an-api-token/) or directly by going to the [credentials page](https://console.scaleway.com/account/organization/credentials). -Note that you will also need to the Organization ID, which can be retrieve on the same page. -Three environment variables are needed to run ExternalDNS with Scaleway DNS: +Two environment variables are needed to run ExternalDNS with Scaleway DNS: - `SCW_ACCESS_KEY` which is the Access Key. - `SCW_SECRET_KEY` which is the Secret Key. -- `SCW_DEFAULT_ORGANIZATION_ID` which is the Default Organization ID. ## Deploy ExternalDNS @@ -63,8 +61,6 @@ spec: value: "" - name: SCW_SECRET_KEY value: "" - - name: SCW_DEFAULT_ORGANIZATION_ID - value: "" ``` ### Manifest (for clusters with RBAC enabled) @@ -131,8 +127,6 @@ spec: value: "" - name: SCW_SECRET_KEY value: "" - - name: SCW_DEFAULT_ORGANIZATION_ID - value: "" ``` From 16b8192783e6921e25cba139ba982160eff55ccf Mon Sep 17 00:00:00 2001 From: Shchukin Konstantin Date: Tue, 24 Jan 2023 12:10:28 +0700 Subject: [PATCH 021/154] create an alias when creord in a zone other than the target --- provider/pdns/pdns.go | 15 +++++++++++---- provider/pdns/pdns_test.go | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/provider/pdns/pdns.go b/provider/pdns/pdns.go index 6f9ca02660..3bfb72490f 100644 --- a/provider/pdns/pdns.go +++ b/provider/pdns/pdns.go @@ -258,6 +258,7 @@ func NewPDNSProvider(ctx context.Context, config PDNSConfig) (*PDNSProvider, err func (p *PDNSProvider) convertRRSetToEndpoints(rr pgo.RrSet) (endpoints []*endpoint.Endpoint, _ error) { endpoints = []*endpoint.Endpoint{} targets := []string{} + rrType_ := rr.Type_ for _, record := range rr.Records { // If a record is "Disabled", it's not supposed to be "visible" @@ -265,8 +266,10 @@ func (p *PDNSProvider) convertRRSetToEndpoints(rr pgo.RrSet) (endpoints []*endpo targets = append(targets, record.Content) } } - - endpoints = append(endpoints, endpoint.NewEndpointWithTTL(rr.Name, rr.Type_, endpoint.TTL(rr.Ttl), targets...)) + if rr.Type_ == "ALIAS" { + rrType_ = "CNAME" + } + endpoints = append(endpoints, endpoint.NewEndpointWithTTL(rr.Name, rrType_, endpoint.TTL(rr.Ttl), targets...)) return endpoints, nil } @@ -311,16 +314,20 @@ func (p *PDNSProvider) ConvertEndpointsToZones(eps []*endpoint.Endpoint, changet // per (ep.DNSName, ep.RecordType) tuple, which holds true for // external-dns v5.0.0-alpha onwards records := []pgo.Record{} + RecordType_ := ep.RecordType for _, t := range ep.Targets { - if ep.RecordType == "CNAME" { + if ep.RecordType == "CNAME" || ep.RecordType == "ALIAS" { t = provider.EnsureTrailingDot(t) + if t != zone.Name && !strings.HasSuffix(t, "."+zone.Name) { + RecordType_ = "ALIAS" + } } records = append(records, pgo.Record{Content: t}) } rrset := pgo.RrSet{ Name: dnsname, - Type_: ep.RecordType, + Type_: RecordType_, Records: records, Changetype: string(changetype), } diff --git a/provider/pdns/pdns_test.go b/provider/pdns/pdns_test.go index 5e7eeb365b..b7108e1ed0 100644 --- a/provider/pdns/pdns_test.go +++ b/provider/pdns/pdns_test.go @@ -82,9 +82,19 @@ var ( Type_: "CNAME", Ttl: 300, Records: []pgo.Record{ - {Content: "example.by.any.other.name.com", Disabled: false, SetPtr: false}, + {Content: "example.com.", Disabled: false, SetPtr: false}, }, } + + RRSetALIASRecord = pgo.RrSet{ + Name: "alias.example.com.", + Type_: "ALIAS", + Ttl: 300, + Records: []pgo.Record{ + {Content: "example.by.any.other.name.com.", Disabled: false, SetPtr: false}, + }, + } + RRSetTXTRecord = pgo.RrSet{ Name: "example.com.", Type_: "TXT", @@ -129,9 +139,10 @@ var ( } endpointsMixedRecords = []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"), + endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.com"), endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "'would smell as sweet'"), endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8", "8.8.4.4", "4.4.4.4"), + endpoint.NewEndpointWithTTL("alias.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"), } endpointsMultipleZones = []*endpoint.Endpoint{ @@ -215,7 +226,7 @@ var ( Type_: "Zone", Url: "/api/v1/servers/localhost/zones/example.com.", Kind: "Native", - Rrsets: []pgo.RrSet{RRSetCNAMERecord, RRSetTXTRecord, RRSetMultipleRecords}, + Rrsets: []pgo.RrSet{RRSetCNAMERecord, RRSetTXTRecord, RRSetMultipleRecords, RRSetALIASRecord}, } ZoneEmptyToSimplePatch = pgo.Zone{ @@ -909,7 +920,7 @@ func (suite *NewPDNSProviderTestSuite) TestPDNSConvertEndpointsToZones() { for _, z := range zlist { for _, rs := range z.Rrsets { - if "CNAME" == rs.Type_ { + if rs.Type_ == "CNAME" { for _, r := range rs.Records { assert.Equal(suite.T(), uint8(0x2e), r.Content[len(r.Content)-1]) } From 6c0f2eb5911a6366b5343f7ac08a39570be86fcd Mon Sep 17 00:00:00 2001 From: vinhas tommy Date: Thu, 26 Jan 2023 15:42:24 +0100 Subject: [PATCH 022/154] fix(gandi): allow grandi provider to support multiple TXT rsetvalues --- provider/gandi/gandi.go | 15 ++++++++++----- provider/gandi/gandi_test.go | 21 ++++----------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/provider/gandi/gandi.go b/provider/gandi/gandi.go index 378b166e8b..6aa60c47c6 100644 --- a/provider/gandi/gandi.go +++ b/provider/gandi/gandi.go @@ -16,7 +16,6 @@ package gandi import ( "context" "errors" - "fmt" "os" "strings" @@ -121,11 +120,17 @@ func (p *GandiProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, erro name = zone } - if len(r.RrsetValues) > 1 { - return nil, fmt.Errorf("can't handle multiple values for rrset %s", name) - } + for _, v := range r.RrsetValues { + log.WithFields(log.Fields{ + "record": r.RrsetName, + "type": r.RrsetType, + "value": v, + "ttl": r.RrsetTTL, + "zone": zone, + }).Info("Rerturning endpoint record") - endpoints = append(endpoints, endpoint.NewEndpoint(name, r.RrsetType, r.RrsetValues[0])) + endpoints = append(endpoints, endpoint.NewEndpoint(name, r.RrsetType, v)) + } } } } diff --git a/provider/gandi/gandi_test.go b/provider/gandi/gandi_test.go index cd9529f05e..bd32d5b6ce 100644 --- a/provider/gandi/gandi_test.go +++ b/provider/gandi/gandi_test.go @@ -18,7 +18,6 @@ import ( "fmt" "os" "reflect" - "strings" "testing" "github.com/go-gandi/go-gandi/domain" @@ -342,7 +341,7 @@ func TestGandiProvider_RecordsAppliesDomainFilter(t *testing.T) { td.Cmp(t, expectedActions, mockedClient.Actions) } -func TestGandiProvider_RecordsErrorOnMultipleValues(t *testing.T) { +func TestGandiProvider_RecordsWithMultipleValues(t *testing.T) { mockedClient := mockGandiClientNewWithRecords([]livedns.DomainRecord{ { RrsetValues: []string{"foo", "bar"}, @@ -355,23 +354,11 @@ func TestGandiProvider_RecordsErrorOnMultipleValues(t *testing.T) { LiveDNSClient: mockedClient, } - expectedActions := []MockAction{ - { - Name: "ListDomains", - }, - { - Name: "GetDomainRecords", - FQDN: "example.com", - }, - } - endpoints, err := mockedProvider.Records(context.Background()) - if err == nil { - t.Errorf("expected to fail") + if err != nil { + t.Errorf("should not fail, %s", err) } - assert.Equal(t, 0, len(endpoints)) - assert.True(t, strings.HasPrefix(err.Error(), "can't handle multiple values for rrset")) - td.Cmp(t, expectedActions, mockedClient.Actions) + assert.Equal(t, 2, len(endpoints)) } func TestGandiProvider_ApplyChangesEmpty(t *testing.T) { From 176fd2ba320c2674127057fadcf1a8f9678c75ec Mon Sep 17 00:00:00 2001 From: vinhas tommy Date: Mon, 30 Jan 2023 08:09:06 +0100 Subject: [PATCH 023/154] improve log on Records --- provider/gandi/gandi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/gandi/gandi.go b/provider/gandi/gandi.go index 6aa60c47c6..3746469ea1 100644 --- a/provider/gandi/gandi.go +++ b/provider/gandi/gandi.go @@ -127,7 +127,7 @@ func (p *GandiProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, erro "value": v, "ttl": r.RrsetTTL, "zone": zone, - }).Info("Rerturning endpoint record") + }).Debug("Returning endpoint record") endpoints = append(endpoints, endpoint.NewEndpoint(name, r.RrsetType, v)) } From b2eebecd680afc9b555a5f3f2b7d09084ca82c1d Mon Sep 17 00:00:00 2001 From: Arunesh Pandey Date: Mon, 6 Mar 2023 11:39:59 -0800 Subject: [PATCH 024/154] Define Labels type and JSON tags for ProviderSpecific fields The current example of CRD source is missing the `Labels` type definition. It also does not have the JSON tag for the `Name` and `Value` fields of the `ProviderSpecificProperty` type. As such, creating a CRD from these types will result in errors. This change fixes the two issues highlighted above. --- docs/contributing/crd-source.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/contributing/crd-source.md b/docs/contributing/crd-source.md index 816b7344b2..40e3814a5b 100644 --- a/docs/contributing/crd-source.md +++ b/docs/contributing/crd-source.md @@ -15,10 +15,11 @@ Here is typical example of [CRD API type](https://github.com/kubernetes-sigs/ext type TTL int64 type Targets []string type ProviderSpecificProperty struct { - Name string - Value string + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` } type ProviderSpecific []ProviderSpecificProperty +type Labels map[string]string type Endpoint struct { // The hostname of the DNS record From 041ca372c889737f848a8ac1ee868cd13f0c22f1 Mon Sep 17 00:00:00 2001 From: Megum1n Date: Tue, 14 Mar 2023 17:16:25 +0100 Subject: [PATCH 025/154] Gloo: Add support for listener.metadataStatic --- source/gloo_proxy.go | 31 +++++++++++++++++++++++++++++-- source/gloo_proxy_test.go | 22 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/source/gloo_proxy.go b/source/gloo_proxy.go index 845ccdee05..09e96ead05 100644 --- a/source/gloo_proxy.go +++ b/source/gloo_proxy.go @@ -64,20 +64,35 @@ type proxySpecHTTPListener struct { } type proxyVirtualHost struct { - Domains []string `json:"domains,omitempty"` - Metadata proxyVirtualHostMetadata `json:"metadata,omitempty"` + Domains []string `json:"domains,omitempty"` + Metadata proxyVirtualHostMetadata `json:"metadata,omitempty"` + MetadataStatic proxyVirtualHostMetadataStatic `json:"metadataStatic,omitempty"` } type proxyVirtualHostMetadata struct { Source []proxyVirtualHostMetadataSource `json:"sources,omitempty"` } +type proxyVirtualHostMetadataStatic struct { + Source []proxyVirtualHostMetadataStaticSource `json:"sources,omitempty"` +} + type proxyVirtualHostMetadataSource struct { Kind string `json:"kind,omitempty"` Name string `json:"name,omitempty"` Namespace string `json:"namespace,omitempty"` } +type proxyVirtualHostMetadataStaticSource struct { + ResourceKind string `json:"resourceKind,omitempty"` + ResourceRef proxyVirtualHostMetadataSourceResourceRef `json:"resourceRef,omitempty"` +} + +type proxyVirtualHostMetadataSourceResourceRef struct { + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` +} + type glooSource struct { dynamicKubeClient dynamic.Interface kubeClient kubernetes.Interface @@ -165,6 +180,18 @@ func (gs *glooSource) annotationsFromProxySource(ctx context.Context, virtualHos } } } + for _, src := range virtualHost.MetadataStatic.Source { + kind := sourceKind(src.ResourceKind) + if kind != nil { + source, err := gs.dynamicKubeClient.Resource(*kind).Namespace(src.ResourceRef.Namespace).Get(ctx, src.ResourceRef.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + for key, value := range source.GetAnnotations() { + annotations[key] = value + } + } + } return annotations, nil } diff --git a/source/gloo_proxy_test.go b/source/gloo_proxy_test.go index c1005fec2b..2df0246666 100644 --- a/source/gloo_proxy_test.go +++ b/source/gloo_proxy_test.go @@ -63,6 +63,17 @@ var internalProxy = proxy{ }, }, }, + MetadataStatic: proxyVirtualHostMetadataStatic{ + Source: []proxyVirtualHostMetadataStaticSource{ + { + ResourceKind: "*v1.Unknown", + ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ + Name: "my-unknown-svc", + Namespace: "unknown", + }, + }, + }, + }, }, { Domains: []string{"c.test"}, @@ -75,6 +86,17 @@ var internalProxy = proxy{ }, }, }, + MetadataStatic: proxyVirtualHostMetadataStatic{ + Source: []proxyVirtualHostMetadataStaticSource{ + { + ResourceKind: "*v1.VirtualService", + ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ + Name: "my-internal-svc", + Namespace: "internal", + }, + }, + }, + }, }, }, }, From 458b702762acba4177dfdb357e021b58d8d683b8 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Tue, 27 Sep 2022 22:56:56 +0200 Subject: [PATCH 026/154] Added traefik source --- docs/tutorials/traefik-proxy.md | 98 +++++ go.mod | 4 +- go.sum | 6 + internal/testutils/endpoint_test.go | 3 +- pkg/apis/externaldns/types.go | 2 +- source/store.go | 10 + source/traefik_proxy.go | 547 ++++++++++++++++++++++++++++ 7 files changed, 667 insertions(+), 3 deletions(-) create mode 100644 docs/tutorials/traefik-proxy.md create mode 100644 source/traefik_proxy.go diff --git a/docs/tutorials/traefik-proxy.md b/docs/tutorials/traefik-proxy.md new file mode 100644 index 0000000000..7857be1b49 --- /dev/null +++ b/docs/tutorials/traefik-proxy.md @@ -0,0 +1,98 @@ +# Configuring ExternalDNS to use the Traefik Proxy Source + +This tutorial describes how to configure ExternalDNS to use the Traefik Proxy source. +It is meant to supplement the other provider-specific setup tutorials. + +## Manifest (for clusters without RBAC enabled) + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns +spec: + strategy: + type: Recreate + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + containers: + - name: external-dns + # update this to the desired external-dns version + image: k8s.gcr.io/external-dns/external-dns:v0.12.2 + args: + - --source=traefik-proxy + - --provider=aws + - --registry=txt + - --txt-owner-id=my-identifier +``` + +## Manifest (for clusters with RBAC enabled) + +Could be change if you have mulitple sources + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: external-dns +rules: +- apiGroups: [""] + resources: ["services","endpoints","pods"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["list","watch"] +- apiGroups: ["traefik.containo.us"] + resources: ["ingressroutes", "ingressroutestcps", "ingressroutesudps"] + verbs: ["get","watch","list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: +- kind: ServiceAccount + name: external-dns + namespace: default +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns +spec: + strategy: + type: Recreate + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + serviceAccountName: external-dns + containers: + - name: external-dns + # update this to the desired external-dns version + image: k8s.gcr.io/external-dns/external-dns:v0.12.2 + args: + - --source=traefik-proxy + - --provider=aws + - --registry=txt + - --txt-owner-id=my-identifier +``` diff --git a/go.mod b/go.mod index de66742d38..30b5915503 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.599 github.com/transip/gotransip/v6 v6.19.0 github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60 - github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 + github.com/vinyldns/go-vinyldns v0.9.16 github.com/vultr/govultr/v2 v2.17.2 go.etcd.io/etcd/api/v3 v3.5.5 go.etcd.io/etcd/client/v3 v3.5.5 @@ -167,6 +167,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/terra-farm/udnssdk v1.3.5 // indirect + github.com/traefik/paerser v0.1.9 // indirect github.com/vektah/gqlparser/v2 v2.5.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.mongodb.org/mongo-driver v1.5.1 // indirect @@ -189,6 +190,7 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/resty.v1 v1.12.0 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect diff --git a/go.sum b/go.sum index bb032b1b7a..e80e8b7fb0 100644 --- a/go.sum +++ b/go.sum @@ -189,6 +189,7 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm 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/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= @@ -197,6 +198,7 @@ github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8n 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 h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= 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= @@ -797,6 +799,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -1171,6 +1175,8 @@ github.com/vektah/gqlparser/v2 v2.5.0 h1:GwEwy7AJsqPWrey0bHnn+3JLaHLZVT66wY/+O+T github.com/vektah/gqlparser/v2 v2.5.0/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 h1:UbVjBjgJUYGD8MlobEdOR+yTeNqaNa2Gf1/nskVNCSE= github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg= +github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ= +github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= diff --git a/internal/testutils/endpoint_test.go b/internal/testutils/endpoint_test.go index ffbb54fb2a..efa472f89e 100644 --- a/internal/testutils/endpoint_test.go +++ b/internal/testutils/endpoint_test.go @@ -19,11 +19,12 @@ package testutils import ( "fmt" "sort" + "testing" "sigs.k8s.io/external-dns/endpoint" ) -func ExampleSameEndpoints() { +func TestExampleSameEndpoints(t *testing.T) { eps := []*endpoint.Endpoint{ { DNSName: "example.org", diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 12759ab32a..688dc0e98d 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -404,7 +404,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(source.DefaultRoutegroupVersion).StringVar(&cfg.SkipperRouteGroupVersion) // Flags related to processing source - app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver") + app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "traefik-proxy") app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName) app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) diff --git a/source/store.go b/source/store.go index 9f5d24b007..52d0dbf93f 100644 --- a/source/store.go +++ b/source/store.go @@ -289,6 +289,16 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg return nil, err } return NewGlooSource(dynamicClient, kubernetesClient, cfg.GlooNamespace) + case "traefik-proxy": + kubernetesClient, err := p.KubeClient() + if err != nil { + return nil, err + } + dynamicClient, err := p.DynamicKubernetesClient() + if err != nil { + return nil, err + } + return NewTraefikSource(ctx, dynamicClient, kubernetesClient, cfg.Namespace, cfg.AnnotationFilter) case "openshift-route": ocpClient, err := p.OpenShiftClient() if err != nil { diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go new file mode 100644 index 0000000000..200f63e07c --- /dev/null +++ b/source/traefik_proxy.go @@ -0,0 +1,547 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "context" + "fmt" + "sort" + + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamicinformer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/cache" + "sigs.k8s.io/external-dns/endpoint" + + traefikV1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" +) + +var ( + ingressrouteGVR = schema.GroupVersionResource{ + Group: traefikV1alpha1.SchemeGroupVersion.Group, + Version: traefikV1alpha1.SchemeGroupVersion.Version, + Resource: "ingressroutes", + } + ingressrouteTCPGVR = schema.GroupVersionResource{ + Group: traefikV1alpha1.SchemeGroupVersion.Group, + Version: traefikV1alpha1.SchemeGroupVersion.Version, + Resource: "ingressroutetcps", + } + ingressrouteUDPGVR = schema.GroupVersionResource{ + Group: traefikV1alpha1.SchemeGroupVersion.Group, + Version: traefikV1alpha1.SchemeGroupVersion.Version, + Resource: "ingressrouteudps", + } +) + +type traefikSource struct { + annotationFilter string + dynamicKubeClient dynamic.Interface + ingressRouteInformer informers.GenericInformer + ingressRouteTcpInformer informers.GenericInformer + ingressRouteUdpInformer informers.GenericInformer + kubeClient kubernetes.Interface + namespace string + unstructuredConverter *unstructuredConverter +} + +func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, kubeClient kubernetes.Interface, namespace string, annotationFilter string) (Source, error) { + // Use shared informer to listen for add/update/delete of Host in the specified namespace. + // Set resync period to 0, to prevent processing when nothing has changed. + informerFactory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(dynamicKubeClient, 0, namespace, nil) + ingressRouteInformer := informerFactory.ForResource(ingressrouteGVR) + ingressRouteTcpInformer := informerFactory.ForResource(ingressrouteTCPGVR) + ingressRouteUdpInformer := informerFactory.ForResource(ingressrouteUDPGVR) + + // Add default resource event handlers to properly initialize informers. + ingressRouteInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) + ingressRouteTcpInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) + ingressRouteUdpInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) + + informerFactory.Start((ctx.Done())) + + // wait for the local cache to be populated. + if err := waitForDynamicCacheSync(context.Background(), informerFactory); err != nil { + return nil, err + } + + uc, err := newTraefikUnstructuredConverter() + if err != nil { + return nil, errors.Wrapf(err, "failed to setup Unstructured Converter") + } + + return &traefikSource{ + annotationFilter: annotationFilter, + dynamicKubeClient: dynamicKubeClient, + ingressRouteInformer: ingressRouteInformer, + ingressRouteTcpInformer: ingressRouteTcpInformer, + ingressRouteUdpInformer: ingressRouteUdpInformer, + kubeClient: kubeClient, + namespace: namespace, + unstructuredConverter: uc, + }, nil +} + +func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + ingressRouteEndpoints, err := ts.ingressRouteEndpoints() + if err != nil { + return nil, err + } + ingressRouteTCPEndpoints, err := ts.ingressRouteTCPEndpoints() + if err != nil { + return nil, err + } + ingressRouteUDPEndpoints, err := ts.ingressRouteUDPEndpoints() + if err != nil { + return nil, err + } + + endpoints = append(endpoints, ingressRouteEndpoints...) + endpoints = append(endpoints, ingressRouteTCPEndpoints...) + endpoints = append(endpoints, ingressRouteUDPEndpoints...) + + for _, ep := range endpoints { + sort.Sort(ep.Targets) + } + + return endpoints, nil +} + +func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.ingressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRoutes []*traefikV1alpha1.IngressRoute + for _, ingressRouteObj := range irs { + unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert") + } + + ingressRoute := &traefikV1alpha1.IngressRoute{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + if err != nil { + return nil, err + } + ingressRoutes = append(ingressRoutes, ingressRoute) + } + + ingressRoutes, err = ts.filterByAnnotationsIngressRoute(ingressRoutes) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRoute") + } + + for _, ingressRoute := range ingressRoutes { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRoute(ingressRoute, ingressEndpoints) + ts.setDualstackLabelIngressRoute(ingressRoute, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} +func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.ingressRouteTcpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRoutes []*traefikV1alpha1.IngressRouteTCP + for _, ingressRouteObj := range irs { + unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert") + } + + ingressRoute := &traefikV1alpha1.IngressRouteTCP{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + if err != nil { + return nil, err + } + ingressRoutes = append(ingressRoutes, ingressRoute) + } + + ingressRoutes, err = ts.filterByAnnotationsIngressRouteTCP(ingressRoutes) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRoute") + } + + for _, ingressRoute := range ingressRoutes { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRoute, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteTCP(ingressRoute, ingressEndpoints) + ts.setDualstackLabelIngressRouteTCP(ingressRoute, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} +func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.ingressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRoutes []*traefikV1alpha1.IngressRouteUDP + for _, ingressRouteObj := range irs { + unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert") + } + + ingressRoute := &traefikV1alpha1.IngressRouteUDP{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + if err != nil { + return nil, err + } + ingressRoutes = append(ingressRoutes, ingressRoute) + } + + ingressRoutes, err = ts.filterByAnnotationsIngressRouteUDP(ingressRoutes) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRoute") + } + + for _, ingressRoute := range ingressRoutes { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRoute, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteUDP(ingressRoute, ingressEndpoints) + ts.setDualstackLabelIngressRouteUDP(ingressRoute, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} + +// filterByAnnotations filters a list of IngressRoute by a given annotation selector. +func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*traefikV1alpha1.IngressRoute) ([]*traefikV1alpha1.IngressRoute, error) { + labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) + if err != nil { + return nil, err + } + selector, err := metav1.LabelSelectorAsSelector(labelSelector) + if err != nil { + return nil, err + } + + // empty filter returns original list + if selector.Empty() { + return ingressRoutes, nil + } + + filteredList := []*traefikV1alpha1.IngressRoute{} + + for _, ingressRoute := range ingressRoutes { + // convert the IngressRoute's annotations to an equivalent label selector + annotations := labels.Set(ingressRoute.Annotations) + + // include IngressRoute if its annotations match the selector + if selector.Matches(annotations) { + filteredList = append(filteredList, ingressRoute) + } + } + + return filteredList, nil +} + +// filterByAnnotations filters a list of IngressRouteTCP by a given annotation selector. +func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*traefikV1alpha1.IngressRouteTCP) ([]*traefikV1alpha1.IngressRouteTCP, error) { + labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) + if err != nil { + return nil, err + } + selector, err := metav1.LabelSelectorAsSelector(labelSelector) + if err != nil { + return nil, err + } + + // empty filter returns original list + if selector.Empty() { + return ingressRoutes, nil + } + + filteredList := []*traefikV1alpha1.IngressRouteTCP{} + + for _, ingressRoute := range ingressRoutes { + // convert the IngressRoute's annotations to an equivalent label selector + annotations := labels.Set(ingressRoute.Annotations) + + // include IngressRoute if its annotations match the selector + if selector.Matches(annotations) { + filteredList = append(filteredList, ingressRoute) + } + } + + return filteredList, nil +} + +// filterByAnnotations filters a list of IngressRoute by a given annotation selector. +func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*traefikV1alpha1.IngressRouteUDP) ([]*traefikV1alpha1.IngressRouteUDP, error) { + labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) + if err != nil { + return nil, err + } + selector, err := metav1.LabelSelectorAsSelector(labelSelector) + if err != nil { + return nil, err + } + + // empty filter returns original list + if selector.Empty() { + return ingressRoutes, nil + } + + filteredList := []*traefikV1alpha1.IngressRouteUDP{} + + for _, ingressRoute := range ingressRoutes { + // convert the IngressRoute's annotations to an equivalent label selector + annotations := labels.Set(ingressRoute.Annotations) + + // include IngressRoute if its annotations match the selector + if selector.Matches(annotations) { + filteredList = append(filteredList, ingressRoute) + } + } + + return filteredList, nil +} + +func (ts *traefikSource) setResourceLabelIngressRoute(ingressroute *traefikV1alpha1.IngressRoute, endpoints []*endpoint.Endpoint) { + for _, ep := range endpoints { + ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressroute/%s/%s", ingressroute.Namespace, ingressroute.Name) + } +} +func (ts *traefikSource) setResourceLabelIngressRouteTCP(ingressroute *traefikV1alpha1.IngressRouteTCP, endpoints []*endpoint.Endpoint) { + for _, ep := range endpoints { + ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressroutetcp/%s/%s", ingressroute.Namespace, ingressroute.Name) + } +} +func (ts *traefikSource) setResourceLabelIngressRouteUDP(ingressroute *traefikV1alpha1.IngressRouteUDP, endpoints []*endpoint.Endpoint) { + for _, ep := range endpoints { + ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressrouteudp/%s/%s", ingressroute.Namespace, ingressroute.Name) + } +} + +func (ts *traefikSource) setDualstackLabelIngressRoute(ingressRoute *traefikV1alpha1.IngressRoute, endpoints []*endpoint.Endpoint) { + val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] + if ok && val == ALBDualstackAnnotationValue { + log.Debugf("Adding dualstack label to IngressRoute %s/%s.", ingressRoute.Namespace, ingressRoute.Name) + for _, ep := range endpoints { + ep.Labels[endpoint.DualstackLabelKey] = "true" + } + } +} +func (ts *traefikSource) setDualstackLabelIngressRouteTCP(ingressRoute *traefikV1alpha1.IngressRouteTCP, endpoints []*endpoint.Endpoint) { + val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] + if ok && val == ALBDualstackAnnotationValue { + log.Debugf("Adding dualstack label to IngressRouteTCP %s/%s.", ingressRoute.Namespace, ingressRoute.Name) + for _, ep := range endpoints { + ep.Labels[endpoint.DualstackLabelKey] = "true" + } + } +} +func (ts *traefikSource) setDualstackLabelIngressRouteUDP(ingressRoute *traefikV1alpha1.IngressRouteUDP, endpoints []*endpoint.Endpoint) { + val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] + if ok && val == ALBDualstackAnnotationValue { + log.Debugf("Adding dualstack label to IngressRouteUDP %s/%s.", ingressRoute.Namespace, ingressRoute.Name) + for _, ep := range endpoints { + ep.Labels[endpoint.DualstackLabelKey] = "true" + } + } +} + +// endpointsFromIngressRoute extracts the endpoints from a IngressRoute object +func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1.IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) + + ttl, err := getTTLFromAnnotations(ingressRoute.Annotations) + if err != nil { + return nil, err + } + + hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations) + for _, hostname := range hostnameList { + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) + } + + // TODO: Implement Traefik router rule logic/regex magic + // if ingressRoute.Spec.Rules != nil { + // for _, rule := range ingressRoute.Spec.Rules { + // if rule.Host != "" { + // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) + // } + // } + // } + + return endpoints, nil +} +func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alpha1.IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) + + ttl, err := getTTLFromAnnotations(ingressRoute.Annotations) + if err != nil { + return nil, err + } + + hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations) + for _, hostname := range hostnameList { + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) + } + + // TODO: Implement Traefik router rule logic/regex magic + // if ingressRoute.Spec.Rules != nil { + // for _, rule := range ingressRoute.Spec.Rules { + // if rule.Host != "" { + // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) + // } + // } + // } + + return endpoints, nil +} +func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *traefikV1alpha1.IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) + + ttl, err := getTTLFromAnnotations(ingressRoute.Annotations) + if err != nil { + return nil, err + } + + hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations) + for _, hostname := range hostnameList { + endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) + } + + // TODO: Implement Traefik router rule logic/regex magic + // if ingressRoute.Spec.Rules != nil { + // for _, rule := range ingressRoute.Spec.Rules { + // if rule.Host != "" { + // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) + // } + // } + // } + + return endpoints, nil +} + +func (ts *traefikSource) AddEventHandler(ctx context.Context, handler func()) { + // Right now there is no way to remove event handler from informer, see: + // https://github.com/kubernetes/kubernetes/issues/79610 + log.Debug("Adding event handler for IngressRoute") + ts.ingressRouteInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + log.Debug("Adding event handler for IngressRouteTCP") + ts.ingressRouteTcpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + log.Debug("Adding event handler for IngressRouteUDP") + ts.ingressRouteUdpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) +} + +// newTraefikUnstructuredConverter returns a new unstructuredConverter initialized +func newTraefikUnstructuredConverter() (*unstructuredConverter, error) { + uc := &unstructuredConverter{ + scheme: runtime.NewScheme(), + } + + // Add the core types we need + uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) + uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) + uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDP{}) + if err := scheme.AddToScheme(uc.scheme); err != nil { + return nil, err + } + + return uc, nil +} From 6c25133bce9b9b627674503af793964ad5875c51 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Tue, 27 Sep 2022 23:40:15 +0200 Subject: [PATCH 027/154] Updated store_test & helm chart clusterrole --- .../external-dns/templates/clusterrole.yaml | 5 +++++ source/store_test.go | 20 +++++++++++++++---- source/traefik_proxy.go | 9 +++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/charts/external-dns/templates/clusterrole.yaml b/charts/external-dns/templates/clusterrole.yaml index 8fcc15dced..6961f05c12 100644 --- a/charts/external-dns/templates/clusterrole.yaml +++ b/charts/external-dns/templates/clusterrole.yaml @@ -70,6 +70,11 @@ rules: resources: ["tcpingresses"] verbs: ["get","watch","list"] {{- end }} +{{- if has "traefik-proxy" .Values.sources }} + - apiGroups: ["traefik.containo.us"] + resources: ["ingressroutes", "ingressroutestcps", "ingressroutesudps"] + verbs: ["get","watch","list"] +{{- end }} {{- if has "openshift-route" .Values.sources }} - apiGroups: ["route.openshift.io"] resources: ["routes"] diff --git a/source/store_test.go b/source/store_test.go index e2d15f3f23..0105b29cc2 100644 --- a/source/store_test.go +++ b/source/store_test.go @@ -130,9 +130,24 @@ func (suite *ByNamesTestSuite) TestAllInitialized() { Version: "v1", Resource: "virtualservers", }: "VirtualServersList", + { + Group: "traefik.containo.us", + Version: "v1alpha1", + Resource: "ingressroutes", + }: "IngressRouteList", + { + Group: "traefik.containo.us", + Version: "v1alpha1", + Resource: "ingressroutetcps", + }: "IngressRouteTCPList", + { + Group: "traefik.containo.us", + Version: "v1alpha1", + Resource: "ingressrouteudps", + }: "IngressRouteUDPList", }), nil) - sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "fake"}, minimalConfig) + sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "traefik-proxy", "fake"}, minimalConfig) suite.NoError(err, "should not generate errors") suite.Len(sources, 7, "should generate all seven sources") } @@ -171,9 +186,6 @@ func (suite *ByNamesTestSuite) TestKubeClientFails() { _, err = ByNames(context.TODO(), mockClientGenerator, []string{"kong-tcpingress"}, minimalConfig) suite.Error(err, "should return an error if kubernetes client cannot be created") - - _, err = ByNames(context.TODO(), mockClientGenerator, []string{"f5-virtualserver"}, minimalConfig) - suite.Error(err, "should return an error if kubernetes client cannot be created") } func (suite *ByNamesTestSuite) TestIstioClientFails() { diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index 200f63e07c..161977c337 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -144,6 +144,7 @@ func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e return endpoints, nil } +// ingressRouteEndpoints extracts endpoints from all IngressRoute objects func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint @@ -196,6 +197,8 @@ func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { return endpoints, nil } + +// ingressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint @@ -248,6 +251,8 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error return endpoints, nil } + +// ingressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint @@ -465,6 +470,8 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1 return endpoints, nil } + +// endpointsFromIngressRouteTCP extracts the endpoints from a IngressRouteTCP object func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alpha1.IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint @@ -491,6 +498,8 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alp return endpoints, nil } + +// endpointsFromIngressRouteUDP extracts the endpoints from a IngressRouteUDP object func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *traefikV1alpha1.IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint From b7016a0f384ab34ab4774a88fa12940f247e34cf Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 28 Sep 2022 21:07:08 +0200 Subject: [PATCH 028/154] Added tests for traefik source --- source/traefik_proxy.go | 56 ++-- source/traefik_proxy_test.go | 625 +++++++++++++++++++++++++++++++++++ 2 files changed, 655 insertions(+), 26 deletions(-) create mode 100644 source/traefik_proxy_test.go diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index 161977c337..d6e7469524 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -19,7 +19,9 @@ package source import ( "context" "fmt" + "regexp" "sort" + "strings" "github.com/pkg/errors" log "github.com/sirupsen/logrus" @@ -57,6 +59,11 @@ var ( } ) +var ( + traefikHostExtractor = regexp.MustCompile(`(?:HostSNI|HostHeader|Host)\s*\(\s*(\x60.*?\x60)\s*\)`) + traefikValueProcessor = regexp.MustCompile(`\x60([^,\x60]+)\x60`) +) + type traefikSource struct { annotationFilter string dynamicKubeClient dynamic.Interface @@ -459,14 +466,17 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1 endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } - // TODO: Implement Traefik router rule logic/regex magic - // if ingressRoute.Spec.Rules != nil { - // for _, rule := range ingressRoute.Spec.Rules { - // if rule.Host != "" { - // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) - // } - // } - // } + for _, route := range ingressRoute.Spec.Routes { + match := route.Match + + for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) { + for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) { + host = strings.TrimPrefix(host, "`") + host = strings.TrimSuffix(host, "`") + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + } + } + } return endpoints, nil } @@ -487,14 +497,17 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alp endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } - // TODO: Implement Traefik router rule logic/regex magic - // if ingressRoute.Spec.Rules != nil { - // for _, rule := range ingressRoute.Spec.Rules { - // if rule.Host != "" { - // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) - // } - // } - // } + for _, route := range ingressRoute.Spec.Routes { + match := route.Match + + for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) { + for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) { + host = strings.TrimPrefix(host, "`") + host = strings.TrimSuffix(host, "`") + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + } + } + } return endpoints, nil } @@ -515,15 +528,6 @@ func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *traefikV1alp endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier)...) } - // TODO: Implement Traefik router rule logic/regex magic - // if ingressRoute.Spec.Rules != nil { - // for _, rule := range ingressRoute.Spec.Rules { - // if rule.Host != "" { - // endpoints = append(endpoints, endpointsForHostname(rule.Host, targets, ttl, providerSpecific, setIdentifier)...) - // } - // } - // } - return endpoints, nil } @@ -547,7 +551,7 @@ func newTraefikUnstructuredConverter() (*unstructuredConverter, error) { // Add the core types we need uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) - uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDP{}) + uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) if err := scheme.AddToScheme(uc.scheme); err != nil { return nil, err } diff --git a/source/traefik_proxy_test.go b/source/traefik_proxy_test.go new file mode 100644 index 0000000000..4b9222684b --- /dev/null +++ b/source/traefik_proxy_test.go @@ -0,0 +1,625 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package source + +import ( + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + traefikV1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + fakeDynamic "k8s.io/client-go/dynamic/fake" + fakeKube "k8s.io/client-go/kubernetes/fake" + "sigs.k8s.io/external-dns/endpoint" +) + +// This is a compile-time validation that traefikSource is a Source. +var _ Source = &traefikSource{} + +const defaultTraefikNamespace = "traefik" + +func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRoute traefikV1alpha1.IngressRoute + expected []*endpoint.Endpoint + }{ + { + title: "IngressRoute with hostname annotation", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with host rule", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteSpec{ + Routes: []traefikV1alpha1.Route{ + { + Match: "Host(`b.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with hostheader rule", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-hostheader-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteSpec{ + Routes: []traefikV1alpha1.Route{ + { + Match: "HostHeader(`c.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "c.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-hostheader-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with multiple host rules", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-multi-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteSpec{ + Routes: []traefikV1alpha1.Route{ + { + Match: "Host(`d.example.com`) || Host(`e.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "d.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "e.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with multiple host rules and annotation", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-multi-host-annotations-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "f.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteSpec{ + Routes: []traefikV1alpha1.Route{ + { + Match: "Host(`g.example.com`, `h.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "f.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "g.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "h.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRoute) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(ingressrouteGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(ingressrouteGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} + +func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRouteTCP traefikV1alpha1.IngressRouteTCP + expected []*endpoint.Endpoint + }{ + { + title: "IngressRouteTCP with hostname annotation", + ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with host sni rule", + ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-hostsni-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteTCPSpec{ + Routes: []traefikV1alpha1.RouteTCP{ + { + Match: "HostSNI(`b.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-hostsni-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple host sni rules", + ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-multi-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteTCPSpec{ + Routes: []traefikV1alpha1.RouteTCP{ + { + Match: "HostSNI(`d.example.com`) || HostSNI(`e.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "d.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "e.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple host sni rules and annotation", + ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-multi-host-annotations-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "f.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteTCPSpec{ + Routes: []traefikV1alpha1.RouteTCP{ + { + Match: "HostSNI(`g.example.com`, `h.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "f.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "g.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "h.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRouteTCP) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(ingressrouteTCPGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(ingressrouteTCPGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} + +func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRouteUDP traefikV1alpha1.IngressRouteUDP + expected []*endpoint.Endpoint + }{ + { + title: "IngressRouteTCP with hostname annotation", + ingressRouteUDP: traefikV1alpha1.IngressRouteUDP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteUDP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressrouteudp-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple hostname annotation", + ingressRouteUDP: traefikV1alpha1.IngressRouteUDP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteUDP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressrouteudp-multi-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com, b.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-multi-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-multi-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRouteUDP) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(ingressrouteUDPGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(ingressrouteUDPGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} From 4ecad141c2e0a980cc2354e64950a3ce7c473156 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 28 Sep 2022 21:18:29 +0200 Subject: [PATCH 029/154] Added exemption for wildcard only route rule --- source/traefik_proxy.go | 13 ++++++++-- source/traefik_proxy_test.go | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index d6e7469524..adb4c015a3 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -473,7 +473,11 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1 for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) { host = strings.TrimPrefix(host, "`") host = strings.TrimSuffix(host, "`") - endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + + // Checking for host = * is required, as Host(`*`) can be set + if host != "*" && host != "" { + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + } } } } @@ -504,7 +508,12 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alp for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) { host = strings.TrimPrefix(host, "`") host = strings.TrimSuffix(host, "`") - endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + + // Checking for host = * is required, as HostSNI(`*`) can be set + // in the case of TLS passthrough + if host != "*" && host != "" { + endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier)...) + } } } } diff --git a/source/traefik_proxy_test.go b/source/traefik_proxy_test.go index 4b9222684b..9e33ca5a58 100644 --- a/source/traefik_proxy_test.go +++ b/source/traefik_proxy_test.go @@ -249,6 +249,31 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, }, }, + { + title: "IngressRoute omit wildcard", + ingressRoute: traefikV1alpha1.IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-omit-wildcard-host", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteSpec{ + Routes: []traefikV1alpha1.Route{ + { + Match: "Host(`*`)", + }, + }, + }, + }, + expected: nil, + }, } { ti := ti t.Run(ti.title, func(t *testing.T) { @@ -466,6 +491,31 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { }, }, }, + { + title: "IngressRouteTCP omit wildcard host sni", + ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-omit-wildcard-host", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikV1alpha1.IngressRouteTCPSpec{ + Routes: []traefikV1alpha1.RouteTCP{ + { + Match: "HostSNI(`*`)", + }, + }, + }, + }, + expected: nil, + }, } { ti := ti t.Run(ti.title, func(t *testing.T) { From 69b8efdedb6ee3bda6272961453b7d1ca6a829ff Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 28 Sep 2022 22:05:07 +0200 Subject: [PATCH 030/154] Fixed rbac permissions in helm chart --- charts/external-dns/templates/clusterrole.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/external-dns/templates/clusterrole.yaml b/charts/external-dns/templates/clusterrole.yaml index 6961f05c12..3c29746d2f 100644 --- a/charts/external-dns/templates/clusterrole.yaml +++ b/charts/external-dns/templates/clusterrole.yaml @@ -72,7 +72,7 @@ rules: {{- end }} {{- if has "traefik-proxy" .Values.sources }} - apiGroups: ["traefik.containo.us"] - resources: ["ingressroutes", "ingressroutestcps", "ingressroutesudps"] + resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps"] verbs: ["get","watch","list"] {{- end }} {{- if has "openshift-route" .Values.sources }} From 7ee3f28876b22ec883ca228e28622eb7215a329f Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 28 Sep 2022 23:51:35 +0200 Subject: [PATCH 031/154] Fixed rbac permissions in documentation --- docs/tutorials/traefik-proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/traefik-proxy.md b/docs/tutorials/traefik-proxy.md index 7857be1b49..e9db468060 100644 --- a/docs/tutorials/traefik-proxy.md +++ b/docs/tutorials/traefik-proxy.md @@ -54,7 +54,7 @@ rules: resources: ["nodes"] verbs: ["list","watch"] - apiGroups: ["traefik.containo.us"] - resources: ["ingressroutes", "ingressroutestcps", "ingressroutesudps"] + resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps"] verbs: ["get","watch","list"] --- apiVersion: rbac.authorization.k8s.io/v1 From 2dcbb2cfd263d7b33baba92fba98437300d2c9d9 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 29 Sep 2022 18:10:00 +0200 Subject: [PATCH 032/154] Removed traefik as dependency --- go.mod | 10 +- go.sum | 9 +- source/traefik_proxy.go | 397 ++++++++++++++++++++++++++++++++--- source/traefik_proxy_test.go | 113 +++++----- 4 files changed, 426 insertions(+), 103 deletions(-) diff --git a/go.mod b/go.mod index 30b5915503..baec316760 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/openshift/api v0.0.0-20210315202829-4b79815405ec github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47 github.com/oracle/oci-go-sdk v24.3.0+incompatible - github.com/ovh/go-ovh v1.1.0 + github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 github.com/pkg/errors v0.9.1 github.com/pluralsh/gqlclient v1.1.6 github.com/projectcontour/contour v1.23.2 @@ -56,7 +56,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.599 github.com/transip/gotransip/v6 v6.19.0 github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60 - github.com/vinyldns/go-vinyldns v0.9.16 + github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 github.com/vultr/govultr/v2 v2.17.2 go.etcd.io/etcd/api/v3 v3.5.5 go.etcd.io/etcd/client/v3 v3.5.5 @@ -113,7 +113,7 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect github.com/go-stack/stack v1.8.0 // indirect - github.com/gofrs/uuid v4.0.0+incompatible // indirect + github.com/gofrs/uuid v3.2.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -167,7 +167,6 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/terra-farm/udnssdk v1.3.5 // indirect - github.com/traefik/paerser v0.1.9 // indirect github.com/vektah/gqlparser/v2 v2.5.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.mongodb.org/mongo-driver v1.5.1 // indirect @@ -190,7 +189,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/resty.v1 v1.12.0 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect @@ -204,4 +202,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a +replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a \ No newline at end of file diff --git a/go.sum b/go.sum index e80e8b7fb0..2d06920f97 100644 --- a/go.sum +++ b/go.sum @@ -189,7 +189,6 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm 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/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= @@ -198,7 +197,6 @@ github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8n 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 h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= 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= @@ -369,7 +367,6 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj 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-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -799,8 +796,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -1175,8 +1170,6 @@ github.com/vektah/gqlparser/v2 v2.5.0 h1:GwEwy7AJsqPWrey0bHnn+3JLaHLZVT66wY/+O+T github.com/vektah/gqlparser/v2 v2.5.0/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 h1:UbVjBjgJUYGD8MlobEdOR+yTeNqaNa2Gf1/nskVNCSE= github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg= -github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ= -github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= @@ -1906,4 +1899,4 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= 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= +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= \ No newline at end of file diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index adb4c015a3..daa7a9bf34 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -37,24 +37,22 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/cache" "sigs.k8s.io/external-dns/endpoint" - - traefikV1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" ) var ( ingressrouteGVR = schema.GroupVersionResource{ - Group: traefikV1alpha1.SchemeGroupVersion.Group, - Version: traefikV1alpha1.SchemeGroupVersion.Version, + Group: "traefik.containo.us", + Version: "v1alpha1", Resource: "ingressroutes", } ingressrouteTCPGVR = schema.GroupVersionResource{ - Group: traefikV1alpha1.SchemeGroupVersion.Group, - Version: traefikV1alpha1.SchemeGroupVersion.Version, + Group: "traefik.containo.us", + Version: "v1alpha1", Resource: "ingressroutetcps", } ingressrouteUDPGVR = schema.GroupVersionResource{ - Group: traefikV1alpha1.SchemeGroupVersion.Group, - Version: traefikV1alpha1.SchemeGroupVersion.Version, + Group: "traefik.containo.us", + Version: "v1alpha1", Resource: "ingressrouteudps", } ) @@ -160,14 +158,14 @@ func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { return nil, err } - var ingressRoutes []*traefikV1alpha1.IngressRoute + var ingressRoutes []*IngressRoute for _, ingressRouteObj := range irs { unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) if !ok { return nil, errors.New("could not convert") } - ingressRoute := &traefikV1alpha1.IngressRoute{} + ingressRoute := &IngressRoute{} err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) if err != nil { return nil, err @@ -214,14 +212,14 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error return nil, err } - var ingressRoutes []*traefikV1alpha1.IngressRouteTCP + var ingressRoutes []*IngressRouteTCP for _, ingressRouteObj := range irs { unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) if !ok { return nil, errors.New("could not convert") } - ingressRoute := &traefikV1alpha1.IngressRouteTCP{} + ingressRoute := &IngressRouteTCP{} err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) if err != nil { return nil, err @@ -268,14 +266,14 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error return nil, err } - var ingressRoutes []*traefikV1alpha1.IngressRouteUDP + var ingressRoutes []*IngressRouteUDP for _, ingressRouteObj := range irs { unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) if !ok { return nil, errors.New("could not convert") } - ingressRoute := &traefikV1alpha1.IngressRouteUDP{} + ingressRoute := &IngressRouteUDP{} err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) if err != nil { return nil, err @@ -314,7 +312,7 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error } // filterByAnnotations filters a list of IngressRoute by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*traefikV1alpha1.IngressRoute) ([]*traefikV1alpha1.IngressRoute, error) { +func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err @@ -329,7 +327,7 @@ func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*traefi return ingressRoutes, nil } - filteredList := []*traefikV1alpha1.IngressRoute{} + filteredList := []*IngressRoute{} for _, ingressRoute := range ingressRoutes { // convert the IngressRoute's annotations to an equivalent label selector @@ -345,7 +343,7 @@ func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*traefi } // filterByAnnotations filters a list of IngressRouteTCP by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*traefikV1alpha1.IngressRouteTCP) ([]*traefikV1alpha1.IngressRouteTCP, error) { +func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*IngressRouteTCP) ([]*IngressRouteTCP, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err @@ -360,7 +358,7 @@ func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*tra return ingressRoutes, nil } - filteredList := []*traefikV1alpha1.IngressRouteTCP{} + filteredList := []*IngressRouteTCP{} for _, ingressRoute := range ingressRoutes { // convert the IngressRoute's annotations to an equivalent label selector @@ -376,7 +374,7 @@ func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*tra } // filterByAnnotations filters a list of IngressRoute by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*traefikV1alpha1.IngressRouteUDP) ([]*traefikV1alpha1.IngressRouteUDP, error) { +func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*IngressRouteUDP) ([]*IngressRouteUDP, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err @@ -391,7 +389,7 @@ func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*tra return ingressRoutes, nil } - filteredList := []*traefikV1alpha1.IngressRouteUDP{} + filteredList := []*IngressRouteUDP{} for _, ingressRoute := range ingressRoutes { // convert the IngressRoute's annotations to an equivalent label selector @@ -406,23 +404,23 @@ func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*tra return filteredList, nil } -func (ts *traefikSource) setResourceLabelIngressRoute(ingressroute *traefikV1alpha1.IngressRoute, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setResourceLabelIngressRoute(ingressroute *IngressRoute, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressroute/%s/%s", ingressroute.Namespace, ingressroute.Name) } } -func (ts *traefikSource) setResourceLabelIngressRouteTCP(ingressroute *traefikV1alpha1.IngressRouteTCP, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setResourceLabelIngressRouteTCP(ingressroute *IngressRouteTCP, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressroutetcp/%s/%s", ingressroute.Namespace, ingressroute.Name) } } -func (ts *traefikSource) setResourceLabelIngressRouteUDP(ingressroute *traefikV1alpha1.IngressRouteUDP, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setResourceLabelIngressRouteUDP(ingressroute *IngressRouteUDP, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingressrouteudp/%s/%s", ingressroute.Namespace, ingressroute.Name) } } -func (ts *traefikSource) setDualstackLabelIngressRoute(ingressRoute *traefikV1alpha1.IngressRoute, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setDualstackLabelIngressRoute(ingressRoute *IngressRoute, endpoints []*endpoint.Endpoint) { val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] if ok && val == ALBDualstackAnnotationValue { log.Debugf("Adding dualstack label to IngressRoute %s/%s.", ingressRoute.Namespace, ingressRoute.Name) @@ -431,7 +429,7 @@ func (ts *traefikSource) setDualstackLabelIngressRoute(ingressRoute *traefikV1al } } } -func (ts *traefikSource) setDualstackLabelIngressRouteTCP(ingressRoute *traefikV1alpha1.IngressRouteTCP, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setDualstackLabelIngressRouteTCP(ingressRoute *IngressRouteTCP, endpoints []*endpoint.Endpoint) { val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] if ok && val == ALBDualstackAnnotationValue { log.Debugf("Adding dualstack label to IngressRouteTCP %s/%s.", ingressRoute.Namespace, ingressRoute.Name) @@ -440,7 +438,7 @@ func (ts *traefikSource) setDualstackLabelIngressRouteTCP(ingressRoute *traefikV } } } -func (ts *traefikSource) setDualstackLabelIngressRouteUDP(ingressRoute *traefikV1alpha1.IngressRouteUDP, endpoints []*endpoint.Endpoint) { +func (ts *traefikSource) setDualstackLabelIngressRouteUDP(ingressRoute *IngressRouteUDP, endpoints []*endpoint.Endpoint) { val, ok := ingressRoute.Annotations[ALBDualstackAnnotationKey] if ok && val == ALBDualstackAnnotationValue { log.Debugf("Adding dualstack label to IngressRouteUDP %s/%s.", ingressRoute.Namespace, ingressRoute.Name) @@ -451,7 +449,7 @@ func (ts *traefikSource) setDualstackLabelIngressRouteUDP(ingressRoute *traefikV } // endpointsFromIngressRoute extracts the endpoints from a IngressRoute object -func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1.IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { +func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) @@ -486,7 +484,7 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *traefikV1alpha1 } // endpointsFromIngressRouteTCP extracts the endpoints from a IngressRouteTCP object -func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alpha1.IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { +func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) @@ -522,7 +520,7 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *traefikV1alp } // endpointsFromIngressRouteUDP extracts the endpoints from a IngressRouteUDP object -func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *traefikV1alpha1.IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { +func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations) @@ -558,12 +556,347 @@ func newTraefikUnstructuredConverter() (*unstructuredConverter, error) { } // Add the core types we need - uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) - uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) - uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) if err := scheme.AddToScheme(uc.scheme); err != nil { return nil, err } return uc, nil } + +// Basic redefinition of Traefik 2's CRD: https://github.com/traefik/traefik/tree/v2.8.7/pkg/provider/kubernetes/crd/traefik/v1alpha1 + +// traefikIngressRouteSpec defines the desired state of IngressRoute. +type traefikIngressRouteSpec struct { + // Routes defines the list of routes. + Routes []traefikRoute `json:"routes"` +} + +// traefikRoute holds the HTTP route configuration. +type traefikRoute struct { + // Match defines the router's rule. + // More info: https://doc.traefik.io/traefik/v2.9/routing/routers/#rule + Match string `json:"match"` +} + +// IngressRoute is the CRD implementation of a Traefik HTTP Router. +type IngressRoute struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata"` + + Spec traefikIngressRouteSpec `json:"spec"` +} + +// IngressRouteList is a collection of IngressRoute. +type IngressRouteList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + + // Items is the list of IngressRoute. + Items []IngressRoute `json:"items"` +} + +// traefikIngressRouteTCPSpec defines the desired state of IngressRouteTCP. +type traefikIngressRouteTCPSpec struct { + Routes []traefikRouteTCP `json:"routes"` +} + +// traefikRouteTCP holds the TCP route configuration. +type traefikRouteTCP struct { + // Match defines the router's rule. + // More info: https://doc.traefik.io/traefik/v2.9/routing/routers/#rule_1 + Match string `json:"match"` +} + +// IngressRouteTCP is the CRD implementation of a Traefik TCP Router. +type IngressRouteTCP struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata"` + + Spec traefikIngressRouteTCPSpec `json:"spec"` +} + +// IngressRouteTCPList is a collection of IngressRouteTCP. +type IngressRouteTCPList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + + // Items is the list of IngressRouteTCP. + Items []IngressRouteTCP `json:"items"` +} + +// IngressRouteUDP is a CRD implementation of a Traefik UDP Router. +type IngressRouteUDP struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata"` +} + +// IngressRouteUDPList is a collection of IngressRouteUDP. +type IngressRouteUDPList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + + // Items is the list of IngressRouteUDP. + Items []IngressRouteUDP `json:"items"` +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRoute) DeepCopyInto(out *IngressRoute) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRoute. +func (in *IngressRoute) DeepCopy() *IngressRoute { + if in == nil { + return nil + } + out := new(IngressRoute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRoute) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteList) DeepCopyInto(out *IngressRouteList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IngressRoute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteList. +func (in *IngressRouteList) DeepCopy() *IngressRouteList { + if in == nil { + return nil + } + out := new(IngressRouteList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *traefikIngressRouteSpec) DeepCopyInto(out *traefikIngressRouteSpec) { + *out = *in + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]traefikRoute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteSpec. +func (in *traefikIngressRouteSpec) DeepCopy() *traefikIngressRouteSpec { + if in == nil { + return nil + } + out := new(traefikIngressRouteSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *traefikRoute) DeepCopyInto(out *traefikRoute) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route. +func (in *traefikRoute) DeepCopy() *traefikRoute { + if in == nil { + return nil + } + out := new(traefikRoute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCP) DeepCopyInto(out *IngressRouteTCP) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCP. +func (in *IngressRouteTCP) DeepCopy() *IngressRouteTCP { + if in == nil { + return nil + } + out := new(IngressRouteTCP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteTCP) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteTCPList) DeepCopyInto(out *IngressRouteTCPList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IngressRouteTCP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPList. +func (in *IngressRouteTCPList) DeepCopy() *IngressRouteTCPList { + if in == nil { + return nil + } + out := new(IngressRouteTCPList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteTCPList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *traefikIngressRouteTCPSpec) DeepCopyInto(out *traefikIngressRouteTCPSpec) { + *out = *in + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]traefikRouteTCP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPSpec. +func (in *traefikIngressRouteTCPSpec) DeepCopy() *traefikIngressRouteTCPSpec { + if in == nil { + return nil + } + out := new(traefikIngressRouteTCPSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *traefikRouteTCP) DeepCopyInto(out *traefikRouteTCP) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTCP. +func (in *traefikRouteTCP) DeepCopy() *traefikRouteTCP { + if in == nil { + return nil + } + out := new(traefikRouteTCP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteUDP) DeepCopyInto(out *IngressRouteUDP) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteUDP. +func (in *IngressRouteUDP) DeepCopy() *IngressRouteUDP { + if in == nil { + return nil + } + out := new(IngressRouteUDP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteUDP) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressRouteUDPList) DeepCopyInto(out *IngressRouteUDPList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IngressRouteUDP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteUDPList. +func (in *IngressRouteUDPList) DeepCopy() *IngressRouteUDPList { + if in == nil { + return nil + } + out := new(IngressRouteUDPList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IngressRouteUDPList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/source/traefik_proxy_test.go b/source/traefik_proxy_test.go index 9e33ca5a58..43bc30e56a 100644 --- a/source/traefik_proxy_test.go +++ b/source/traefik_proxy_test.go @@ -22,7 +22,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - traefikV1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -41,14 +40,14 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { for _, ti := range []struct { title string - ingressRoute traefikV1alpha1.IngressRoute + ingressRoute IngressRoute expected []*endpoint.Endpoint }{ { title: "IngressRoute with hostname annotation", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -76,9 +75,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, { title: "IngressRoute with host rule", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -89,8 +88,8 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteSpec{ - Routes: []traefikV1alpha1.Route{ + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ { Match: "Host(`b.example.com`)", }, @@ -112,9 +111,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, { title: "IngressRoute with hostheader rule", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -125,8 +124,8 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteSpec{ - Routes: []traefikV1alpha1.Route{ + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ { Match: "HostHeader(`c.example.com`)", }, @@ -148,9 +147,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, { title: "IngressRoute with multiple host rules", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -161,8 +160,8 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteSpec{ - Routes: []traefikV1alpha1.Route{ + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ { Match: "Host(`d.example.com`) || Host(`e.example.com`)", }, @@ -194,9 +193,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, { title: "IngressRoute with multiple host rules and annotation", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -208,8 +207,8 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteSpec{ - Routes: []traefikV1alpha1.Route{ + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ { Match: "Host(`g.example.com`, `h.example.com`)", }, @@ -251,9 +250,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { }, { title: "IngressRoute omit wildcard", - ingressRoute: traefikV1alpha1.IngressRoute{ + ingressRoute: IngressRoute{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteGVR.GroupVersion().String(), Kind: "IngressRoute", }, ObjectMeta: metav1.ObjectMeta{ @@ -264,8 +263,8 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteSpec{ - Routes: []traefikV1alpha1.Route{ + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ { Match: "Host(`*`)", }, @@ -281,9 +280,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { fakeKubernetesClient := fakeKube.NewSimpleClientset() scheme := runtime.NewScheme() - scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) - scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) - scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} @@ -319,14 +318,14 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { for _, ti := range []struct { title string - ingressRouteTCP traefikV1alpha1.IngressRouteTCP + ingressRouteTCP IngressRouteTCP expected []*endpoint.Endpoint }{ { title: "IngressRouteTCP with hostname annotation", - ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + ingressRouteTCP: IngressRouteTCP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteTCPGVR.GroupVersion().String(), Kind: "IngressRouteTCP", }, ObjectMeta: metav1.ObjectMeta{ @@ -354,9 +353,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { }, { title: "IngressRouteTCP with host sni rule", - ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + ingressRouteTCP: IngressRouteTCP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteTCPGVR.GroupVersion().String(), Kind: "IngressRouteTCP", }, ObjectMeta: metav1.ObjectMeta{ @@ -367,8 +366,8 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteTCPSpec{ - Routes: []traefikV1alpha1.RouteTCP{ + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ { Match: "HostSNI(`b.example.com`)", }, @@ -390,9 +389,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { }, { title: "IngressRouteTCP with multiple host sni rules", - ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + ingressRouteTCP: IngressRouteTCP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteTCPGVR.GroupVersion().String(), Kind: "IngressRouteTCP", }, ObjectMeta: metav1.ObjectMeta{ @@ -403,8 +402,8 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteTCPSpec{ - Routes: []traefikV1alpha1.RouteTCP{ + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ { Match: "HostSNI(`d.example.com`) || HostSNI(`e.example.com`)", }, @@ -436,9 +435,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { }, { title: "IngressRouteTCP with multiple host sni rules and annotation", - ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + ingressRouteTCP: IngressRouteTCP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteTCPGVR.GroupVersion().String(), Kind: "IngressRouteTCP", }, ObjectMeta: metav1.ObjectMeta{ @@ -450,8 +449,8 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteTCPSpec{ - Routes: []traefikV1alpha1.RouteTCP{ + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ { Match: "HostSNI(`g.example.com`, `h.example.com`)", }, @@ -493,9 +492,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { }, { title: "IngressRouteTCP omit wildcard host sni", - ingressRouteTCP: traefikV1alpha1.IngressRouteTCP{ + ingressRouteTCP: IngressRouteTCP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteTCPGVR.GroupVersion().String(), Kind: "IngressRouteTCP", }, ObjectMeta: metav1.ObjectMeta{ @@ -506,8 +505,8 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { "kubernetes.io/ingress.class": "traefik", }, }, - Spec: traefikV1alpha1.IngressRouteTCPSpec{ - Routes: []traefikV1alpha1.RouteTCP{ + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ { Match: "HostSNI(`*`)", }, @@ -523,9 +522,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { fakeKubernetesClient := fakeKube.NewSimpleClientset() scheme := runtime.NewScheme() - scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) - scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) - scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} @@ -561,14 +560,14 @@ func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { for _, ti := range []struct { title string - ingressRouteUDP traefikV1alpha1.IngressRouteUDP + ingressRouteUDP IngressRouteUDP expected []*endpoint.Endpoint }{ { title: "IngressRouteTCP with hostname annotation", - ingressRouteUDP: traefikV1alpha1.IngressRouteUDP{ + ingressRouteUDP: IngressRouteUDP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteUDPGVR.GroupVersion().String(), Kind: "IngressRouteUDP", }, ObjectMeta: metav1.ObjectMeta{ @@ -596,9 +595,9 @@ func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { }, { title: "IngressRouteTCP with multiple hostname annotation", - ingressRouteUDP: traefikV1alpha1.IngressRouteUDP{ + ingressRouteUDP: IngressRouteUDP{ TypeMeta: metav1.TypeMeta{ - APIVersion: traefikV1alpha1.SchemeGroupVersion.String(), + APIVersion: ingressrouteUDPGVR.GroupVersion().String(), Kind: "IngressRouteUDP", }, ObjectMeta: metav1.ObjectMeta{ @@ -641,9 +640,9 @@ func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { fakeKubernetesClient := fakeKube.NewSimpleClientset() scheme := runtime.NewScheme() - scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &traefikV1alpha1.IngressRoute{}, &traefikV1alpha1.IngressRouteList{}) - scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteTCP{}, &traefikV1alpha1.IngressRouteTCPList{}) - scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &traefikV1alpha1.IngressRouteUDP{}, &traefikV1alpha1.IngressRouteUDPList{}) + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} From dba5dcb6bd5ddb6c08b30f12c05ebbf520980761 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 29 Sep 2022 18:11:54 +0200 Subject: [PATCH 033/154] Readded newlines to file endings of go mod files --- go.mod | 2 +- go.sum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index baec316760..9f6495b352 100644 --- a/go.mod +++ b/go.mod @@ -202,4 +202,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a \ No newline at end of file +replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a diff --git a/go.sum b/go.sum index 2d06920f97..cf72a12c4b 100644 --- a/go.sum +++ b/go.sum @@ -1899,4 +1899,4 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= 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= \ No newline at end of file +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= From e8b5bf38d339766e8191d768087484980f3f536e Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Sun, 15 Jan 2023 22:06:44 +0100 Subject: [PATCH 034/154] Moving helm chart changes to separate branch --- charts/external-dns/templates/clusterrole.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/charts/external-dns/templates/clusterrole.yaml b/charts/external-dns/templates/clusterrole.yaml index 3c29746d2f..8fcc15dced 100644 --- a/charts/external-dns/templates/clusterrole.yaml +++ b/charts/external-dns/templates/clusterrole.yaml @@ -70,11 +70,6 @@ rules: resources: ["tcpingresses"] verbs: ["get","watch","list"] {{- end }} -{{- if has "traefik-proxy" .Values.sources }} - - apiGroups: ["traefik.containo.us"] - resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps"] - verbs: ["get","watch","list"] -{{- end }} {{- if has "openshift-route" .Values.sources }} - apiGroups: ["route.openshift.io"] resources: ["routes"] From 6ba9d3b221d75aedd73bc484aee03d42ebabcc06 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Sun, 15 Jan 2023 22:25:50 +0100 Subject: [PATCH 035/154] Fixed error thrown by linter --- source/traefik_proxy.go | 1 + 1 file changed, 1 insertion(+) diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index daa7a9bf34..9e4b09b392 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -36,6 +36,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/cache" + "sigs.k8s.io/external-dns/endpoint" ) From e5422811a32ba6e200fe12b6229fa6305d5344a7 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Fri, 3 Feb 2023 23:31:23 +0100 Subject: [PATCH 036/154] Updated docs --- docs/tutorials/traefik-proxy.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/traefik-proxy.md b/docs/tutorials/traefik-proxy.md index e9db468060..325d7a1d60 100644 --- a/docs/tutorials/traefik-proxy.md +++ b/docs/tutorials/traefik-proxy.md @@ -24,7 +24,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: k8s.gcr.io/external-dns/external-dns:v0.12.2 + image: k8s.gcr.io/external-dns/external-dns:v0.13.3 args: - --source=traefik-proxy - --provider=aws @@ -34,8 +34,6 @@ spec: ## Manifest (for clusters with RBAC enabled) -Could be change if you have mulitple sources - ```yaml apiVersion: v1 kind: ServiceAccount @@ -89,7 +87,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: k8s.gcr.io/external-dns/external-dns:v0.12.2 + image: k8s.gcr.io/external-dns/external-dns:v0.13.3 args: - --source=traefik-proxy - --provider=aws From f527b54e2e057d580f4708424dde37bf110bc6f6 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Fri, 17 Mar 2023 15:24:48 +0100 Subject: [PATCH 037/154] Fixed store tests --- go.mod | 4 ++-- go.sum | 32 +++++++------------------------- source/store_test.go | 2 +- 3 files changed, 10 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 9f6495b352..de66742d38 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/openshift/api v0.0.0-20210315202829-4b79815405ec github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47 github.com/oracle/oci-go-sdk v24.3.0+incompatible - github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 + github.com/ovh/go-ovh v1.1.0 github.com/pkg/errors v0.9.1 github.com/pluralsh/gqlclient v1.1.6 github.com/projectcontour/contour v1.23.2 @@ -113,7 +113,7 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect github.com/go-stack/stack v1.8.0 // indirect - github.com/gofrs/uuid v3.2.0+incompatible // indirect + github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect diff --git a/go.sum b/go.sum index cf72a12c4b..8786ee822d 100644 --- a/go.sum +++ b/go.sum @@ -27,9 +27,8 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -256,8 +255,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma 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/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/datawire/ambassador v1.6.0 h1:4KduhY/wqtv0jK8sMVQNtENHy9fmoXugsuFp/UrM0Ts= github.com/datawire/ambassador v1.6.0/go.mod h1:mV5EhoG/NnHBsffmLnjrq+x4ZNkYDWFZXW9R+AueUiE= @@ -367,6 +366,7 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj 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-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -594,7 +594,6 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC 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/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= 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/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= @@ -1309,7 +1308,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB 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.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -1360,13 +1358,10 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R 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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1464,11 +1459,11 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1508,6 +1503,7 @@ 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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -1518,15 +1514,11 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/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= @@ -1594,6 +1586,7 @@ golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -1666,18 +1659,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc h1:ijGwO+0vL2hJt5gaygqP2j6PfflOBrRot0IczKbmtio= google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= diff --git a/source/store_test.go b/source/store_test.go index 0105b29cc2..773475b69e 100644 --- a/source/store_test.go +++ b/source/store_test.go @@ -149,7 +149,7 @@ func (suite *ByNamesTestSuite) TestAllInitialized() { sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "traefik-proxy", "fake"}, minimalConfig) suite.NoError(err, "should not generate errors") - suite.Len(sources, 7, "should generate all seven sources") + suite.Len(sources, 8, "should generate all eight sources") } func (suite *ByNamesTestSuite) TestOnlyFake() { From 205e8c0334fe07065de0fedb1f92fa85a43450b9 Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Thu, 30 Mar 2023 19:58:18 +0100 Subject: [PATCH 038/154] Add support for MX records in Azure, GCP and AWS --- endpoint/endpoint.go | 2 + provider/aws/aws.go | 11 +++- provider/azure/azure.go | 36 ++++++++++++- provider/azure/azure_private_dns.go | 25 +++++++++ provider/azure/azure_privatedns_test.go | 25 +++++++++ provider/azure/azure_test.go | 27 ++++++++++ provider/azure/common.go | 33 ++++++++++++ provider/azure/common_test.go | 71 +++++++++++++++++++++++++ provider/google/google.go | 18 ++++++- provider/google/google_test.go | 2 + 10 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 provider/azure/common.go create mode 100644 provider/azure/common_test.go diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 428a7961b6..dba536dcdc 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -40,6 +40,8 @@ const ( RecordTypeNS = "NS" // RecordTypePTR is a RecordType enum value RecordTypePTR = "PTR" + // RecordTypeMX is a RecordType enum value + RecordTypeMX = "MX" ) // TTL is a structure defining the TTL of a DNS record diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 5f7457420e..4a21e39dd1 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -373,7 +373,7 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos for _, r := range resp.ResourceRecordSets { newEndpoints := make([]*endpoint.Endpoint, 0) - if !provider.SupportedRecordType(aws.StringValue(r.Type)) { + if !p.SupportedRecordType(aws.StringValue(r.Type)) { continue } @@ -1059,3 +1059,12 @@ func canonicalHostedZone(hostname string) string { func cleanZoneID(id string) string { return strings.TrimPrefix(id, "/hostedzone/") } + +func (p *AWSProvider) SupportedRecordType(recordType string) bool { + switch recordType { + case "MX": + return true + default: + return provider.SupportedRecordType(recordType) + } +} diff --git a/provider/azure/azure.go b/provider/azure/azure.go index dfab96effa..24a0e0ecbe 100644 --- a/provider/azure/azure.go +++ b/provider/azure/azure.go @@ -109,7 +109,7 @@ func (p *AzureProvider) Records(ctx context.Context) (endpoints []*endpoint.Endp return true } recordType := strings.TrimPrefix(*recordSet.Type, "Microsoft.Network/dnszones/") - if !provider.SupportedRecordType(recordType) { + if !p.SupportedRecordType(recordType) { return true } name := formatAzureDNSName(*recordSet.Name, *zone.Name) @@ -190,6 +190,15 @@ func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) { return zones, nil } +func (p *AzureProvider) SupportedRecordType(recordType string) bool { + switch recordType { + case "MX": + return true + default: + return provider.SupportedRecordType(recordType) + } +} + func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error { log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName) @@ -377,6 +386,21 @@ func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet }, }, }, nil + case dns.MX: + mxRecords := make([]dns.MxRecord, len(endpoint.Targets)) + for i, target := range endpoint.Targets { + mxRecord, err := parseMxTarget[dns.MxRecord](target) + if err != nil { + return dns.RecordSet{}, err + } + mxRecords[i] = mxRecord + } + return dns.RecordSet{ + RecordSetProperties: &dns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + MxRecords: &mxRecords, + }, + }, nil case dns.TXT: return dns.RecordSet{ RecordSetProperties: &dns.RecordSetProperties{ @@ -425,6 +449,16 @@ func extractAzureTargets(recordSet *dns.RecordSet) []string { return []string{*cnameRecord.Cname} } + // Check for MX records + mxRecords := properties.MxRecords + if mxRecords != nil && len(*mxRecords) > 0 && (*mxRecords)[0].Exchange != nil { + targets := make([]string, len(*mxRecords)) + for i, mxRecord := range *mxRecords { + targets[i] = fmt.Sprintf("%d %s", *mxRecord.Preference, *mxRecord.Exchange) + } + return targets + } + // Check for TXT records txtRecords := properties.TxtRecords if txtRecords != nil && len(*txtRecords) > 0 && (*txtRecords)[0].Value != nil { diff --git a/provider/azure/azure_private_dns.go b/provider/azure/azure_private_dns.go index 374b5e5d6c..fd5733bfe1 100644 --- a/provider/azure/azure_private_dns.go +++ b/provider/azure/azure_private_dns.go @@ -367,6 +367,21 @@ func (p *AzurePrivateDNSProvider) newRecordSet(endpoint *endpoint.Endpoint) (pri }, }, }, nil + case privatedns.MX: + mxRecords := make([]privatedns.MxRecord, len(endpoint.Targets)) + for i, target := range endpoint.Targets { + mxRecord, err := parseMxTarget[privatedns.MxRecord](target) + if err != nil { + return privatedns.RecordSet{}, err + } + mxRecords[i] = mxRecord + } + return privatedns.RecordSet{ + RecordSetProperties: &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + MxRecords: &mxRecords, + }, + }, nil case privatedns.TXT: return privatedns.RecordSet{ RecordSetProperties: &privatedns.RecordSetProperties{ @@ -407,6 +422,16 @@ func extractAzurePrivateDNSTargets(recordSet *privatedns.RecordSet) []string { return []string{*cnameRecord.Cname} } + // Check for MX records + mxRecords := properties.MxRecords + if mxRecords != nil && len(*mxRecords) > 0 && (*mxRecords)[0].Exchange != nil { + targets := make([]string, len(*mxRecords)) + for i, mxRecord := range *mxRecords { + targets[i] = fmt.Sprintf("%d %s", *mxRecord.Preference, *mxRecord.Exchange) + } + return targets + } + // Check for TXT records txtRecords := properties.TxtRecords if txtRecords != nil && len(*txtRecords) > 0 && (*txtRecords)[0].Value != nil { diff --git a/provider/azure/azure_privatedns_test.go b/provider/azure/azure_privatedns_test.go index f357201548..e728659c4a 100644 --- a/provider/azure/azure_privatedns_test.go +++ b/provider/azure/azure_privatedns_test.go @@ -123,6 +123,17 @@ func privateCNameRecordSetPropertiesGetter(values []string, ttl int64) *privated } } +func privateMXRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { + mxRecords := make([]privatedns.MxRecord, len(values)) + for i, target := range values { + mxRecords[i], _ = parseMxTarget[privatedns.MxRecord](target) + } + return &privatedns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + MxRecords: &mxRecords, + } +} + func privateTxtRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties { return &privatedns.RecordSetProperties{ TTL: to.Int64Ptr(ttl), @@ -156,6 +167,8 @@ func createPrivateMockRecordSetMultiWithTTL(name, recordType string, ttl int64, getterFunc = privateARecordSetPropertiesGetter case endpoint.RecordTypeCNAME: getterFunc = privateCNameRecordSetPropertiesGetter + case endpoint.RecordTypeMX: + getterFunc = privateMXRecordSetPropertiesGetter case endpoint.RecordTypeTXT: getterFunc = privateTxtRecordSetPropertiesGetter default: @@ -266,6 +279,7 @@ func TestAzurePrivateDNSRecord(t *testing.T) { createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + createPrivateMockRecordSetWithTTL("mail", endpoint.RecordTypeMX, "10 example.com", 4000), }) if err != nil { t.Fatal(err) @@ -281,6 +295,7 @@ func TestAzurePrivateDNSRecord(t *testing.T) { endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, 4000, "10 example.com"), } validateAzureEndpoints(t, actual, expected) @@ -299,6 +314,7 @@ func TestAzurePrivateDNSMultiRecord(t *testing.T) { createPrivateMockRecordSetMultiWithTTL("nginx", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), createPrivateMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createPrivateMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + createPrivateMockRecordSetMultiWithTTL("mail", endpoint.RecordTypeMX, 4000, "10 example.com", "20 backup.example.com"), }) if err != nil { t.Fatal(err) @@ -314,6 +330,7 @@ func TestAzurePrivateDNSMultiRecord(t *testing.T) { endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, 4000, "10 example.com", "20 backup.example.com"), } validateAzureEndpoints(t, actual, expected) @@ -329,6 +346,7 @@ func TestAzurePrivateDNSApplyChanges(t *testing.T) { endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, ""), endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, ""), endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, ""), + endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, ""), }) validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ @@ -342,6 +360,9 @@ func TestAzurePrivateDNSApplyChanges(t *testing.T) { endpoint.NewEndpointWithTTL("other.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), + endpoint.NewEndpointWithTTL("newmail.example.com", endpoint.RecordTypeMX, 7200, "40 bar.other.com"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 other.com"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), }) } @@ -401,17 +422,21 @@ func testAzurePrivateDNSApplyChangesInternal(t *testing.T, dryRun bool, client P endpoint.NewEndpoint("other.com", endpoint.RecordTypeTXT, "tag"), endpoint.NewEndpoint("nope.com", endpoint.RecordTypeA, "4.4.4.4"), endpoint.NewEndpoint("nope.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("mail.example.com", endpoint.RecordTypeMX, "10 other.com"), + endpoint.NewEndpoint("mail.example.com", endpoint.RecordTypeTXT, "tag"), } currentRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, "121.212.121.212"), endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, "other.com"), endpoint.NewEndpoint("old.nope.com", endpoint.RecordTypeA, "121.212.121.212"), + endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, "20 foo.other.com"), } updatedRecords := []*endpoint.Endpoint{ endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), endpoint.NewEndpoint("new.nope.com", endpoint.RecordTypeA, "222.111.222.111"), + endpoint.NewEndpointWithTTL("newmail.example.com", endpoint.RecordTypeMX, 7200, "40 bar.other.com"), } deleteRecords := []*endpoint.Endpoint{ diff --git a/provider/azure/azure_test.go b/provider/azure/azure_test.go index 0598dd4f3c..050ab3d923 100644 --- a/provider/azure/azure_test.go +++ b/provider/azure/azure_test.go @@ -122,6 +122,17 @@ func cNameRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetPr } } +func mxRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties { + mxRecords := make([]dns.MxRecord, len(values)) + for i, target := range values { + mxRecords[i], _ = parseMxTarget[dns.MxRecord](target) + } + return &dns.RecordSetProperties{ + TTL: to.Int64Ptr(ttl), + MxRecords: &mxRecords, + } +} + func txtRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties { return &dns.RecordSetProperties{ TTL: to.Int64Ptr(ttl), @@ -155,6 +166,8 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values getterFunc = aRecordSetPropertiesGetter case endpoint.RecordTypeCNAME: getterFunc = cNameRecordSetPropertiesGetter + case endpoint.RecordTypeMX: + getterFunc = mxRecordSetPropertiesGetter case endpoint.RecordTypeTXT: getterFunc = txtRecordSetPropertiesGetter default: @@ -271,6 +284,7 @@ func TestAzureRecord(t *testing.T) { createMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + createMockRecordSetMultiWithTTL("mail", endpoint.RecordTypeMX, 4000, "10 example.com"), }) if err != nil { t.Fatal(err) @@ -287,6 +301,7 @@ func TestAzureRecord(t *testing.T) { endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, 4000, "10 example.com"), } validateAzureEndpoints(t, actual, expected) @@ -305,6 +320,7 @@ func TestAzureMultiRecord(t *testing.T) { createMockRecordSetMultiWithTTL("nginx", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), + createMockRecordSetMultiWithTTL("mail", endpoint.RecordTypeMX, 4000, "10 example.com", "20 backup.example.com"), }) if err != nil { t.Fatal(err) @@ -321,6 +337,7 @@ func TestAzureMultiRecord(t *testing.T) { endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123", "234.234.234.234"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), endpoint.NewEndpointWithTTL("hack.example.com", endpoint.RecordTypeCNAME, 10, "hack.azurewebsites.net"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, 4000, "10 example.com", "20 backup.example.com"), } validateAzureEndpoints(t, actual, expected) @@ -336,6 +353,7 @@ func TestAzureApplyChanges(t *testing.T) { endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, ""), endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, ""), endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, ""), + endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, ""), }) validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ @@ -349,6 +367,9 @@ func TestAzureApplyChanges(t *testing.T) { endpoint.NewEndpointWithTTL("other.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), + endpoint.NewEndpointWithTTL("newmail.example.com", endpoint.RecordTypeMX, 7200, "40 bar.other.com"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 other.com"), + endpoint.NewEndpointWithTTL("mail.example.com", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "tag"), }) } @@ -410,17 +431,21 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC endpoint.NewEndpoint("other.com", endpoint.RecordTypeTXT, "tag"), endpoint.NewEndpoint("nope.com", endpoint.RecordTypeA, "4.4.4.4"), endpoint.NewEndpoint("nope.com", endpoint.RecordTypeTXT, "tag"), + endpoint.NewEndpoint("mail.example.com", endpoint.RecordTypeMX, "10 other.com"), + endpoint.NewEndpoint("mail.example.com", endpoint.RecordTypeTXT, "tag"), } currentRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, "121.212.121.212"), endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, "other.com"), endpoint.NewEndpoint("old.nope.com", endpoint.RecordTypeA, "121.212.121.212"), + endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, "20 foo.other.com"), } updatedRecords := []*endpoint.Endpoint{ endpoint.NewEndpointWithTTL("new.example.com", endpoint.RecordTypeA, 3600, "111.222.111.222"), endpoint.NewEndpointWithTTL("newcname.example.com", endpoint.RecordTypeCNAME, 10, "other.com"), endpoint.NewEndpoint("new.nope.com", endpoint.RecordTypeA, "222.111.222.111"), + endpoint.NewEndpointWithTTL("newmail.example.com", endpoint.RecordTypeMX, 7200, "40 bar.other.com"), } deleteRecords := []*endpoint.Endpoint{ @@ -455,6 +480,7 @@ func TestAzureNameFilter(t *testing.T) { createMockRecordSetWithTTL("test.nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeA, "123.123.123.123", 3600), createMockRecordSetWithTTL("nginx", endpoint.RecordTypeTXT, "heritage=external-dns,external-dns/owner=default", recordTTL), + createMockRecordSetWithTTL("mail.nginx", endpoint.RecordTypeMX, "20 example.com", recordTTL), createMockRecordSetWithTTL("hack", endpoint.RecordTypeCNAME, "hack.azurewebsites.net", 10), }) if err != nil { @@ -470,6 +496,7 @@ func TestAzureNameFilter(t *testing.T) { endpoint.NewEndpointWithTTL("test.nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeA, 3600, "123.123.123.123"), endpoint.NewEndpointWithTTL("nginx.example.com", endpoint.RecordTypeTXT, recordTTL, "heritage=external-dns,external-dns/owner=default"), + endpoint.NewEndpointWithTTL("mail.nginx.example.com", endpoint.RecordTypeMX, recordTTL, "20 example.com"), } validateAzureEndpoints(t, actual, expected) diff --git a/provider/azure/common.go b/provider/azure/common.go new file mode 100644 index 0000000000..15ecf64cff --- /dev/null +++ b/provider/azure/common.go @@ -0,0 +1,33 @@ +package azure + +import ( + "fmt" + "strconv" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/Azure/go-autorest/autorest/to" +) + +// Helper function (shared with test code) +func parseMxTarget[T dns.MxRecord | privatedns.MxRecord](mxTarget string) (T, error) { + targetParts := strings.SplitN(mxTarget, " ", 2) + + if len(targetParts) != 2 { + return T{}, fmt.Errorf("mx target needs to be of form '10 example.com'") + } + + preferenceRaw, exchange := targetParts[0], targetParts[1] + preference, err := strconv.ParseInt(preferenceRaw, 10, 32) + + if err != nil { + return T{}, fmt.Errorf("invalid preference specified") + } + res := T{ + Preference: to.Int32Ptr(int32(preference)), + Exchange: to.StringPtr(exchange), + } + + return res, nil +} diff --git a/provider/azure/common_test.go b/provider/azure/common_test.go new file mode 100644 index 0000000000..b7f4d8dfd7 --- /dev/null +++ b/provider/azure/common_test.go @@ -0,0 +1,71 @@ +package azure + +import ( + "fmt" + "testing" + + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" + "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns" + "github.com/Azure/go-autorest/autorest/to" + + "github.com/stretchr/testify/assert" +) + +func Test_parseMxTarget(t *testing.T) { + type testCase[T interface { + dns.MxRecord | privatedns.MxRecord + }] struct { + name string + args string + want T + wantErr assert.ErrorAssertionFunc + } + + tests := []testCase[dns.MxRecord]{ + { + name: "valid mx target", + args: "10 example.com", + want: dns.MxRecord{ + Preference: to.Int32Ptr(int32(10)), + Exchange: to.StringPtr("example.com"), + }, + wantErr: assert.NoError, + }, + { + name: "valid mx target with a subdomain", + args: "99 foo-bar.example.com", + want: dns.MxRecord{ + Preference: to.Int32Ptr(int32(99)), + Exchange: to.StringPtr("foo-bar.example.com"), + }, + wantErr: assert.NoError, + }, + { + name: "invalid mx target with misplaced preference and exchange", + args: "example.com 10", + want: dns.MxRecord{}, + wantErr: assert.Error, + }, + { + name: "invalid mx target without preference", + args: "example.com", + want: dns.MxRecord{}, + wantErr: assert.Error, + }, + { + name: "invalid mx target with non numeric preference", + args: "aa example.com", + want: dns.MxRecord{}, + wantErr: assert.Error, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseMxTarget[dns.MxRecord](tt.args) + if !tt.wantErr(t, err, fmt.Sprintf("parseMxTarget(%v)", tt.args)) { + return + } + assert.Equalf(t, tt.want, got, "parseMxTarget(%v)", tt.args) + }) + } +} diff --git a/provider/google/google.go b/provider/google/google.go index d6c53ef6ab..5fce653f58 100644 --- a/provider/google/google.go +++ b/provider/google/google.go @@ -213,7 +213,7 @@ func (p *GoogleProvider) Records(ctx context.Context) (endpoints []*endpoint.End f := func(resp *dns.ResourceRecordSetsListResponse) error { for _, r := range resp.Rrsets { - if !provider.SupportedRecordType(r.Type) { + if !p.SupportedRecordType(r.Type) { continue } endpoints = append(endpoints, endpoint.NewEndpointWithTTL(r.Name, r.Type, endpoint.TTL(r.Ttl), r.Rrdatas...)) @@ -273,6 +273,16 @@ func (p *GoogleProvider) ApplyChanges(ctx context.Context, changes *plan.Changes return p.submitChange(ctx, change) } +// SupportedRecordType returns true if the record type is supported by the provider +func (p *GoogleProvider) SupportedRecordType(recordType string) bool { + switch recordType { + case "MX": + return true + default: + return provider.SupportedRecordType(recordType) + } +} + // newFilteredRecords returns a collection of RecordSets based on the given endpoints and domainFilter. func (p *GoogleProvider) newFilteredRecords(endpoints []*endpoint.Endpoint) []*dns.ResourceRecordSet { records := []*dns.ResourceRecordSet{} @@ -447,6 +457,12 @@ func newRecord(ep *endpoint.Endpoint) *dns.ResourceRecordSet { targets[0] = provider.EnsureTrailingDot(targets[0]) } + if ep.RecordType == endpoint.RecordTypeMX { + for i, mxRecord := range ep.Targets { + targets[i] = provider.EnsureTrailingDot(mxRecord) + } + } + // no annotation results in a Ttl of 0, default to 300 for backwards-compatibility var ttl int64 = googleRecordTTL if ep.RecordTTL.IsConfigured() { diff --git a/provider/google/google_test.go b/provider/google/google_test.go index 3fe6100914..bc321200b7 100644 --- a/provider/google/google_test.go +++ b/provider/google/google_test.go @@ -512,6 +512,7 @@ func TestNewFilteredRecords(t *testing.T) { endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do", endpoint.RecordTypeCNAME, 4000, "bar.elb.amazonaws.com"), // test fallback to Ttl:300 when Ttl==0 : endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.gcp.zalan.do", endpoint.RecordTypeA, 0, "8.8.8.8"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.gcp.zalan.do", endpoint.RecordTypeMX, 6000, "10 mail.elb.amazonaws.com"), endpoint.NewEndpoint("delete-test.zone-1.ext-dns-test-2.gcp.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"), }) @@ -521,6 +522,7 @@ func TestNewFilteredRecords(t *testing.T) { {Name: "delete-test.zone-2.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"8.8.4.4"}, Type: "A", Ttl: 120}, {Name: "update-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"bar.elb.amazonaws.com."}, Type: "CNAME", Ttl: 4000}, {Name: "update-test.zone-1.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"8.8.8.8"}, Type: "A", Ttl: 300}, + {Name: "update-test-mx.zone-1.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"10 mail.elb.amazonaws.com."}, Type: "MX", Ttl: 6000}, {Name: "delete-test.zone-1.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"8.8.8.8"}, Type: "A", Ttl: 300}, {Name: "delete-test-cname.zone-1.ext-dns-test-2.gcp.zalan.do.", Rrdatas: []string{"qux.elb.amazonaws.com."}, Type: "CNAME", Ttl: 300}, }) From 4c02b1c64878951d59b83387f5bc0bb984c7bb2f Mon Sep 17 00:00:00 2001 From: Sewci0 Date: Fri, 31 Mar 2023 11:20:02 +0100 Subject: [PATCH 039/154] Update common.go --- provider/azure/common.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/provider/azure/common.go b/provider/azure/common.go index 15ecf64cff..dc87bc3b30 100644 --- a/provider/azure/common.go +++ b/provider/azure/common.go @@ -24,10 +24,8 @@ func parseMxTarget[T dns.MxRecord | privatedns.MxRecord](mxTarget string) (T, er if err != nil { return T{}, fmt.Errorf("invalid preference specified") } - res := T{ + return T{ Preference: to.Int32Ptr(int32(preference)), Exchange: to.StringPtr(exchange), - } - - return res, nil + }, nil } From 761f0e94f62d25c7057a2d331b6748530f4c3d70 Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Fri, 31 Mar 2023 11:44:03 +0100 Subject: [PATCH 040/154] Add licence --- provider/azure/common.go | 16 ++++++++++++++++ provider/azure/common_test.go | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/provider/azure/common.go b/provider/azure/common.go index dc87bc3b30..5b5ee2c5ea 100644 --- a/provider/azure/common.go +++ b/provider/azure/common.go @@ -1,3 +1,19 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package azure import ( diff --git a/provider/azure/common_test.go b/provider/azure/common_test.go index b7f4d8dfd7..1009594c26 100644 --- a/provider/azure/common_test.go +++ b/provider/azure/common_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package azure import ( From b265cbf937781622613ea3b7168bc26fbd3e235e Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Fri, 31 Mar 2023 13:14:27 +0100 Subject: [PATCH 041/154] Add no lint --- provider/azure/common.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provider/azure/common.go b/provider/azure/common.go index 5b5ee2c5ea..10aa62d036 100644 --- a/provider/azure/common.go +++ b/provider/azure/common.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// nolint:staticcheck package azure import ( From 574c1025ce1386d6bab90a987e4458e93f47b3f2 Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Fri, 31 Mar 2023 13:23:14 +0100 Subject: [PATCH 042/154] Fix whitespace --- provider/azure/common.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/provider/azure/common.go b/provider/azure/common.go index 10aa62d036..e6c45ece20 100644 --- a/provider/azure/common.go +++ b/provider/azure/common.go @@ -30,17 +30,16 @@ import ( // Helper function (shared with test code) func parseMxTarget[T dns.MxRecord | privatedns.MxRecord](mxTarget string) (T, error) { targetParts := strings.SplitN(mxTarget, " ", 2) - if len(targetParts) != 2 { return T{}, fmt.Errorf("mx target needs to be of form '10 example.com'") } preferenceRaw, exchange := targetParts[0], targetParts[1] preference, err := strconv.ParseInt(preferenceRaw, 10, 32) - if err != nil { return T{}, fmt.Errorf("invalid preference specified") } + return T{ Preference: to.Int32Ptr(int32(preference)), Exchange: to.StringPtr(exchange), From 4c546fb73a4cf526e3913b996091043054ccec48 Mon Sep 17 00:00:00 2001 From: Maurice Meyer Date: Fri, 31 Mar 2023 17:34:20 +0200 Subject: [PATCH 043/154] docs: add example for provider specific config --- docs/contributing/crd-source/dnsendpoint-example.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/contributing/crd-source/dnsendpoint-example.yaml b/docs/contributing/crd-source/dnsendpoint-example.yaml index 894301d8ae..2ed7d7fa01 100644 --- a/docs/contributing/crd-source/dnsendpoint-example.yaml +++ b/docs/contributing/crd-source/dnsendpoint-example.yaml @@ -9,3 +9,7 @@ spec: recordType: A targets: - 192.168.99.216 + # Provider specific configurations are set like an annotation would on other sources + providerSpecific: + - name: external-dns.alpha.kubernetes.io/cloudflare-proxied + value: "true" From 2554f9f879d3364156f878f4db619224a69aa7a3 Mon Sep 17 00:00:00 2001 From: Viacheslav Sychov Date: Fri, 28 Apr 2023 20:29:54 +0200 Subject: [PATCH 044/154] #1828: Support encrypted DNS txt records Signed-off-by: Viacheslav Sychov --- docs/registry.md | 65 +++++++++++++++++ endpoint/crypto.go | 134 ++++++++++++++++++++++++++++++++++ endpoint/crypto_test.go | 58 +++++++++++++++ endpoint/labels.go | 56 +++++++++++++- endpoint/labels_test.go | 71 +++++++++++++----- main.go | 2 +- pkg/apis/externaldns/types.go | 6 ++ provider/awssd/aws_sd.go | 2 +- registry/aws_sd_registry.go | 4 +- registry/txt.go | 23 ++++-- registry/txt_test.go | 54 ++++++++------ 11 files changed, 423 insertions(+), 52 deletions(-) create mode 100644 endpoint/crypto.go create mode 100644 endpoint/crypto_test.go diff --git a/docs/registry.md b/docs/registry.md index 615ba305a6..3ff20b93a7 100644 --- a/docs/registry.md +++ b/docs/registry.md @@ -13,3 +13,68 @@ The controller will try to create the "new format" TXT records if they are not p Later on, the old format will be dropped and only the new format will be kept (-). Cleanup will be done by controller itself. + +### Encryption of TXT Records +TXT records may contain sensitive information, such as the internal ingress name or namespace, which attackers could exploit to gather information about your infrastructure. +By encrypting TXT records, you can protect this information from unauthorized access. It is strongly recommended to encrypt all TXT records to prevent potential security breaches. + +To enable encryption of TXT records, you can use the following parameters: +- `--txt-encrypt-enabled=true` +- `--txt-encrypt-aes-key=32bytesKey` (used for AES-256-GCM encryption and should be exactly 32 bytes) + +Note that the key used for encryption should be a secure key and properly managed to ensure the security of your TXT records. + +### Generating TXT encryption AES key +Python +```python +python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())' +``` + +Bash +```shell +dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo +``` + +OpenSSL +```shell +openssl rand -base64 32 | tr -- '+/' '-_' +``` + +PowerShell +```powershell +# Add System.Web assembly to session, just in case +Add-Type -AssemblyName System.Web +[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([System.Web.Security.Membership]::GeneratePassword(32,4))).Replace("+","-").Replace("/","_") +``` + +Terraform +```hcl +resource "random_password" "txt_key" { + length = 32 + override_special = "-_" +} +``` + +### Manually Encrypt/Decrypt TXT Records + +In some cases, you may need to edit labels generated by External-DNS, and in such cases, you can use simple Golang code to do that. + +```go +package main + +import ( + "fmt" + "sigs.k8s.io/external-dns/endpoint" +) + +func main() { + key := []byte("testtesttesttesttesttesttesttest") + encrypted, _ := endpoint.EncryptText( + "heritage=external-dns,external-dns/owner=example,external-dns/resource=ingress/default/example", + key, + nil, + ) + decrypted, _, _ := endpoint.DecryptText(encrypted, key) + fmt.Println(decrypted) +} +``` diff --git a/endpoint/crypto.go b/endpoint/crypto.go new file mode 100644 index 0000000000..1d6ebd1dd7 --- /dev/null +++ b/endpoint/crypto.go @@ -0,0 +1,134 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endpoint + +import ( + "bytes" + "compress/gzip" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "fmt" + "io" + + log "github.com/sirupsen/logrus" +) + +// EncryptText gzip input data and encrypts it using the supplied AES key +func EncryptText(text string, aesKey []byte, nonceEncoded []byte) (string, error) { + block, err := aes.NewCipher(aesKey) + if err != nil { + return "", err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + nonce := make([]byte, gcm.NonceSize()) + if nonceEncoded == nil { + if _, err = io.ReadFull(rand.Reader, nonce); err != nil { + return "", err + } + } else { + if _, err = base64.StdEncoding.Decode(nonce, nonceEncoded); err != nil { + return "", err + } + } + + data, err := compressData([]byte(text)) + if err != nil { + return "", err + } + + cipherData := gcm.Seal(nonce, nonce, data, nil) + return base64.StdEncoding.EncodeToString(cipherData), nil +} + +// DecryptText decrypt gziped data using a supplied AES encryption key ang ungzip it +// in case of decryption failed, will return original input and decryption error +func DecryptText(text string, aesKey []byte) (decryptResult string, encryptNonce string, err error) { + block, err := aes.NewCipher(aesKey) + if err != nil { + return "", "", err + } + gcm, err := cipher.NewGCM(block) + if err != nil { + return "", "", err + } + nonceSize := gcm.NonceSize() + data, err := base64.StdEncoding.DecodeString(text) + if err != nil { + return "", "", err + } + if len(data) <= nonceSize { + return "", "", fmt.Errorf("the encoded data from text %#v is shorter than %#v bytes and can't be decoded", text, nonceSize) + } + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + plaindata, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return "", "", err + } + plaindata, err = decompressData(plaindata) + if err != nil { + log.Debugf("Failed to decompress data based on the base64 encoded text %#v. Got error %#v.", text, err) + return "", "", err + } + + return string(plaindata), base64.StdEncoding.EncodeToString(nonce), nil +} + +// decompressData gzip compressed data +func decompressData(data []byte) (resData []byte, err error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, err + } + defer gz.Close() + var b bytes.Buffer + if _, err = b.ReadFrom(gz); err != nil { + return nil, err + } + + return b.Bytes(), nil +} + +// compressData by gzip, for minify data stored in registry +func compressData(data []byte) (compressedData []byte, err error) { + var b bytes.Buffer + gz, err := gzip.NewWriterLevel(&b, gzip.BestCompression) + if err != nil { + return nil, err + } + + defer gz.Close() + if _, err = gz.Write(data); err != nil { + return nil, err + } + + if err = gz.Flush(); err != nil { + return nil, err + } + + if err = gz.Close(); err != nil { + return nil, err + } + + return b.Bytes(), nil +} diff --git a/endpoint/crypto_test.go b/endpoint/crypto_test.go new file mode 100644 index 0000000000..880afcce3a --- /dev/null +++ b/endpoint/crypto_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endpoint + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEncrypt(t *testing.T) { + // Verify that text encryption and decryption works + aesKey := []byte("s%zF`.*'5`9.AhI2!B,.~hmbs^.*TL?;") + plaintext := "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." + encryptedtext, err := EncryptText(plaintext, aesKey, nil) + require.NoError(t, err) + decryptedtext, _, err := DecryptText(encryptedtext, aesKey) + require.NoError(t, err) + if plaintext != decryptedtext { + t.Errorf("Original plain text %#v differs from the resulting decrypted text %#v", plaintext, decryptedtext) + } + + // Verify that decrypt returns an error and empty data if wrong AES encryption key is used + decryptedtext, _, err = DecryptText(encryptedtext, []byte("s'J!jD`].LC?g&Oa11AgTub,j48ts/96")) + require.Error(t, err) + if decryptedtext != "" { + t.Error("Data decryption failed, empty string should be as result") + } + + // Verify that decrypt returns an error and empty data if unencrypted input is is supplied + decryptedtext, _, err = DecryptText(plaintext, aesKey) + require.Error(t, err) + if decryptedtext != "" { + t.Errorf("Data decryption failed, empty string should be as result") + } + + // Verify that a known encrypted text is decrypted to what is expected + encryptedtext = "0Mfzf6wsN8llrfX0ucDZ6nlc2+QiQfKKedjPPLu5atb2I35L9nUZeJcCnuLVW7CVW3K0h94vSuBLdXnMrj8Vcm0M09shxaoF48IcCpD03XtQbKXqk2hPbsW6+JybvplHIQGr16/PcjUSObGmR9yjf38+qEltApkKvrPjsyw43BX4eE10rL0Bln33UJD7/w+zazRDPFlAcbGtkt0ETKHnvyB3/aCddLipvrhjCXj2ZY/ktRF6h716kJRgXU10dCIQHFYU45MIdxI+k10HK3yZqhI2V0Gp2xjrFV/LRQ7/OS9SFee4asPWUYxbCEsnOzp8qc0dCPFSo1dtADzWnUZnsAcbnjtudT4milfLJc5CxDk1v3ykqQ/ajejwHjWQ7b8U6AsTErbezfdcqrb5IzkLgHb5TosnfrdDmNc9GcKfpsrCHbVY8KgNwMVdtwavLv7d9WM6sooUlZ3t0sABGkzagXQmPRvwLnkSOlie5XrnzWo8/8/4UByLga29CaXO" + decryptedtext, _, err = DecryptText(encryptedtext, aesKey) + require.NoError(t, err) + if decryptedtext != plaintext { + t.Error("Decryption of text didn't result in expected plaintext result.") + } +} diff --git a/endpoint/labels.go b/endpoint/labels.go index 797190db41..c65333dc6e 100644 --- a/endpoint/labels.go +++ b/endpoint/labels.go @@ -17,6 +17,8 @@ limitations under the License. package endpoint import ( + log "github.com/sirupsen/logrus" + "errors" "fmt" "sort" @@ -41,6 +43,9 @@ const ( // DualstackLabelKey is the name of the label that identifies dualstack endpoints DualstackLabelKey = "dualstack" + + // txtEncryptionNonce label for keep same nonce for same txt records, for prevent different result of encryption for same txt record, it can cause issues for some providers + txtEncryptionNonce = "txt-encryption-nonce" ) // Labels store metadata related to the endpoint @@ -55,7 +60,7 @@ func NewLabels() Labels { // NewLabelsFromString constructs endpoints labels from a provided format string // if heritage set to another value is found then error is returned // no heritage automatically assumes is not owned by external-dns and returns invalidHeritage error -func NewLabelsFromString(labelText string) (Labels, error) { +func NewLabelsFromStringPlain(labelText string) (Labels, error) { endpointLabels := map[string]string{} labelText = strings.Trim(labelText, "\"") // drop quotes tokens := strings.Split(labelText, ",") @@ -85,9 +90,26 @@ func NewLabelsFromString(labelText string) (Labels, error) { return endpointLabels, nil } -// Serialize transforms endpoints labels into a external-dns recognizable format string +func NewLabelsFromString(labelText string, aesKey []byte) (Labels, error) { + if len(aesKey) != 0 { + decryptedText, encryptionNonce, err := DecryptText(strings.Trim(labelText, "\""), aesKey) + //in case if we have decryption error, just try process original text + //decryption errors should be ignored here, because we can already have plain-text labels in registry + if err == nil { + labels, err := NewLabelsFromStringPlain(decryptedText) + if err == nil { + labels[txtEncryptionNonce] = encryptionNonce + } + + return labels, err + } + } + return NewLabelsFromStringPlain(labelText) +} + +// SerializePlain transforms endpoints labels into a external-dns recognizable format string // withQuotes adds additional quotes -func (l Labels) Serialize(withQuotes bool) string { +func (l Labels) SerializePlain(withQuotes bool) string { var tokens []string tokens = append(tokens, fmt.Sprintf("heritage=%s", heritage)) var keys []string @@ -104,3 +126,31 @@ func (l Labels) Serialize(withQuotes bool) string { } return strings.Join(tokens, ",") } + +// Serialize same to SerializePlain, but encrypt data, if encryption enabled +func (l Labels) Serialize(withQuotes bool, txtEncryptEnabled bool, aesKey []byte) string { + if !txtEncryptEnabled { + return l.SerializePlain(withQuotes) + } + + var encryptionNonce []byte = nil + if extractedNonce, nonceExists := l[txtEncryptionNonce]; nonceExists { + encryptionNonce = []byte(extractedNonce) + delete(l, txtEncryptionNonce) + } + + text := l.SerializePlain(false) + log.Debugf("Encrypt the serialized text %#v before returning it.", text) + var err error + text, err = EncryptText(text, aesKey, encryptionNonce) + + if err != nil { + log.Fatalf("Failed to encrypt the text %#v using the encryption key %#v. Got error %#v.", text, aesKey, err) + } + + if withQuotes { + text = fmt.Sprintf("\"%s\"", text) + } + log.Debugf("Serialized text after encryption is %#v.", text) + return text +} diff --git a/endpoint/labels_test.go b/endpoint/labels_test.go index 9386a23e6a..394635b710 100644 --- a/endpoint/labels_test.go +++ b/endpoint/labels_test.go @@ -25,14 +25,18 @@ import ( type LabelsSuite struct { suite.Suite - foo Labels - fooAsText string - fooAsTextWithQuotes string - barText string - barTextAsMap Labels - noHeritageText string - wrongHeritageText string - multipleHeritageText string // considered invalid + aesKey []byte + foo Labels + fooAsText string + fooAsTextWithQuotes string + fooAsTextEncrypted string + fooAsTextWithQuotesEncrypted string + barText string + barTextEncrypted string + barTextAsMap Labels + noHeritageText string + wrongHeritageText string + multipleHeritageText string // considered invalid } func (suite *LabelsSuite) SetupTest() { @@ -40,48 +44,79 @@ func (suite *LabelsSuite) SetupTest() { "owner": "foo-owner", "resource": "foo-resource", } + suite.aesKey = []byte(")K_Fy|?Z.64#UuHm`}[d!GC%WJM_fs{_") suite.fooAsText = "heritage=external-dns,external-dns/owner=foo-owner,external-dns/resource=foo-resource" suite.fooAsTextWithQuotes = fmt.Sprintf(`"%s"`, suite.fooAsText) - + suite.fooAsTextEncrypted = `+lvP8q9KHJ6BS6O81i2Q6DLNdf2JSKy8j/gbZKviTZlGYj7q+yDoYMgkQ1hPn6urtGllM5bfFMcaaHto52otQtiOYrX8990J3kQqg4s47m3bH3Ejl8RSxSSuWJM3HJtPghQzYg0/LSOsdQ0=` + suite.fooAsTextWithQuotesEncrypted = fmt.Sprintf(`"%s"`, suite.fooAsTextEncrypted) suite.barTextAsMap = map[string]string{ "owner": "bar-owner", "resource": "bar-resource", "new-key": "bar-new-key", } suite.barText = "heritage=external-dns,,external-dns/owner=bar-owner,external-dns/resource=bar-resource,external-dns/new-key=bar-new-key,random=stuff,no-equal-sign,," // also has some random gibberish - + suite.barTextEncrypted = "yi6vVATlgYN0enXBIupVK2atNUKtajofWMroWtvZjUanFZXlWvqjJPpjmMd91kv86bZj+syQEP0uR3TK6eFVV7oKFh/NxYyh238FjZ+25zlXW9TgbLoMalUNOkhKFdfXkLeeaqJjePB59t+kQBYX+ZEryK652asPs6M+xTIvtg07N7WWZ6SjJujm0RRISg==" suite.noHeritageText = "external-dns/owner=random-owner" suite.wrongHeritageText = "heritage=mate,external-dns/owner=random-owner" suite.multipleHeritageText = "heritage=mate,heritage=external-dns,external-dns/owner=random-owner" } func (suite *LabelsSuite) TestSerialize() { - suite.Equal(suite.fooAsText, suite.foo.Serialize(false), "should serializeLabel") - suite.Equal(suite.fooAsTextWithQuotes, suite.foo.Serialize(true), "should serializeLabel") + suite.Equal(suite.fooAsText, suite.foo.SerializePlain(false), "should serializeLabel") + suite.Equal(suite.fooAsTextWithQuotes, suite.foo.SerializePlain(true), "should serializeLabel") + suite.Equal(suite.fooAsText, suite.foo.Serialize(false, false, nil), "should serializeLabel") + suite.Equal(suite.fooAsTextWithQuotes, suite.foo.Serialize(true, false, nil), "should serializeLabel") + suite.Equal(suite.fooAsText, suite.foo.Serialize(false, false, suite.aesKey), "should serializeLabel") + suite.Equal(suite.fooAsTextWithQuotes, suite.foo.Serialize(true, false, suite.aesKey), "should serializeLabel") + suite.NotEqual(suite.fooAsText, suite.foo.Serialize(false, true, suite.aesKey), "should serializeLabel and encrypt") + suite.NotEqual(suite.fooAsTextWithQuotes, suite.foo.Serialize(true, true, suite.aesKey), "should serializeLabel and encrypt") +} + +func (suite *LabelsSuite) TestEncryptionNonceReUsage() { + foo, err := NewLabelsFromString(suite.fooAsTextEncrypted, suite.aesKey) + suite.NoError(err, "should succeed for valid label text") + serialized := foo.Serialize(false, true, suite.aesKey) + suite.Equal(serialized, suite.fooAsTextEncrypted, "serialized result should be equal") } func (suite *LabelsSuite) TestDeserialize() { - foo, err := NewLabelsFromString(suite.fooAsText) + foo, err := NewLabelsFromStringPlain(suite.fooAsText) suite.NoError(err, "should succeed for valid label text") suite.Equal(suite.foo, foo, "should reconstruct original label map") - foo, err = NewLabelsFromString(suite.fooAsTextWithQuotes) + foo, err = NewLabelsFromStringPlain(suite.fooAsTextWithQuotes) suite.NoError(err, "should succeed for valid label text") suite.Equal(suite.foo, foo, "should reconstruct original label map") - bar, err := NewLabelsFromString(suite.barText) + foo, err = NewLabelsFromString(suite.fooAsTextEncrypted, suite.aesKey) + suite.NoError(err, "should succeed for valid encrypted label text") + for key, val := range suite.foo { + suite.Equal(val, foo[key], "should contains all keys from original label map") + } + + foo, err = NewLabelsFromString(suite.fooAsTextWithQuotesEncrypted, suite.aesKey) + suite.NoError(err, "should succeed for valid encrypted label text") + for key, val := range suite.foo { + suite.Equal(val, foo[key], "should contains all keys from original label map") + } + + bar, err := NewLabelsFromStringPlain(suite.barText) suite.NoError(err, "should succeed for valid label text") suite.Equal(suite.barTextAsMap, bar, "should reconstruct original label map") - noHeritage, err := NewLabelsFromString(suite.noHeritageText) + bar, err = NewLabelsFromString(suite.barText, suite.aesKey) + suite.NoError(err, "should succeed for valid encrypted label text") + suite.Equal(suite.barTextAsMap, bar, "should reconstruct original label map") + + noHeritage, err := NewLabelsFromStringPlain(suite.noHeritageText) suite.Equal(ErrInvalidHeritage, err, "should fail if no heritage is found") suite.Nil(noHeritage, "should return nil") - wrongHeritage, err := NewLabelsFromString(suite.wrongHeritageText) + wrongHeritage, err := NewLabelsFromStringPlain(suite.wrongHeritageText) suite.Equal(ErrInvalidHeritage, err, "should fail if wrong heritage is found") suite.Nil(wrongHeritage, "if error should return nil") - multipleHeritage, err := NewLabelsFromString(suite.multipleHeritageText) + multipleHeritage, err := NewLabelsFromStringPlain(suite.multipleHeritageText) suite.Equal(ErrInvalidHeritage, err, "should fail if multiple heritage is found") suite.Nil(multipleHeritage, "if error should return nil") } diff --git a/main.go b/main.go index 960045ce98..0e6e37e28d 100644 --- a/main.go +++ b/main.go @@ -382,7 +382,7 @@ func main() { case "noop": r, err = registry.NewNoopRegistry(p) case "txt": - r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes) + r, err = registry.NewTXTRegistry(p, cfg.TXTPrefix, cfg.TXTSuffix, cfg.TXTOwnerID, cfg.TXTCacheInterval, cfg.TXTWildcardReplacement, cfg.ManagedDNSRecordTypes, cfg.TXTEncryptEnabled, []byte(cfg.TXTEncryptAESKey)) case "aws-sd": r, err = registry.NewAWSSDRegistry(p.(*awssd.AWSSDProvider), cfg.TXTOwnerID) default: diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index eefd2b2bf0..a4ca2ab66a 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -147,6 +147,8 @@ type Config struct { TXTOwnerID string TXTPrefix string TXTSuffix string + TXTEncryptEnabled bool + TXTEncryptAESKey string Interval time.Duration MinEventSyncInterval time.Duration Once bool @@ -295,6 +297,8 @@ var defaultConfig = &Config{ TXTCacheInterval: 0, TXTWildcardReplacement: "", MinEventSyncInterval: 5 * time.Second, + TXTEncryptEnabled: false, + TXTEncryptAESKey: "", Interval: time.Minute, Once: false, DryRun: false, @@ -570,6 +574,8 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("txt-prefix", "When using the TXT registry, a custom string that's prefixed to each ownership DNS record (optional). Could contain record type template like '%{record_type}-prefix-'. Mutual exclusive with txt-suffix!").Default(defaultConfig.TXTPrefix).StringVar(&cfg.TXTPrefix) app.Flag("txt-suffix", "When using the TXT registry, a custom string that's suffixed to the host portion of each ownership DNS record (optional). Could contain record type template like '-%{record_type}-suffix'. Mutual exclusive with txt-prefix!").Default(defaultConfig.TXTSuffix).StringVar(&cfg.TXTSuffix) app.Flag("txt-wildcard-replacement", "When using the TXT registry, a custom string that's used instead of an asterisk for TXT records corresponding to wildcard DNS records (optional)").Default(defaultConfig.TXTWildcardReplacement).StringVar(&cfg.TXTWildcardReplacement) + app.Flag("txt-encrypt-enabled", "When using the TXT registry, set if TXT records should be encrypted before stored (default: disabled)").BoolVar(&cfg.TXTEncryptEnabled) + app.Flag("txt-encrypt-aes-key", "When using the TXT registry, set TXT record decryption and encryption 32 byte aes key (required when --txt-encrypt=true)").Default(defaultConfig.TXTEncryptAESKey).StringVar(&cfg.TXTEncryptAESKey) // Flags related to the main control loop app.Flag("txt-cache-interval", "The interval between cache synchronizations in duration format (default: disabled)").Default(defaultConfig.TXTCacheInterval.String()).DurationVar(&cfg.TXTCacheInterval) diff --git a/provider/awssd/aws_sd.go b/provider/awssd/aws_sd.go index ecdb7efc58..97cca81cc1 100644 --- a/provider/awssd/aws_sd.go +++ b/provider/awssd/aws_sd.go @@ -509,7 +509,7 @@ func (p *AWSSDProvider) DeleteService(service *sd.Service) error { // convert ownerID string to service description format label := endpoint.NewLabels() label[endpoint.OwnerLabelKey] = p.ownerID - label[endpoint.AWSSDDescriptionLabel] = label.Serialize(false) + label[endpoint.AWSSDDescriptionLabel] = label.SerializePlain(false) if strings.HasPrefix(aws.StringValue(service.Description), label[endpoint.AWSSDDescriptionLabel]) { log.Infof("Deleting service \"%s\"", *service.Name) diff --git a/registry/aws_sd_registry.go b/registry/aws_sd_registry.go index a2ff3350d8..f0fef584d9 100644 --- a/registry/aws_sd_registry.go +++ b/registry/aws_sd_registry.go @@ -55,7 +55,7 @@ func (sdr *AWSSDRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, er } for _, record := range records { - labels, err := endpoint.NewLabelsFromString(record.Labels[endpoint.AWSSDDescriptionLabel]) + labels, err := endpoint.NewLabelsFromStringPlain(record.Labels[endpoint.AWSSDDescriptionLabel]) if err != nil { // if we fail to parse the output then simply assume the endpoint is not managed by any instance of External DNS record.Labels = endpoint.NewLabels() @@ -96,7 +96,7 @@ func (sdr *AWSSDRegistry) updateLabels(endpoints []*endpoint.Endpoint) { ep.Labels = make(map[string]string) } ep.Labels[endpoint.OwnerLabelKey] = sdr.ownerID - ep.Labels[endpoint.AWSSDDescriptionLabel] = ep.Labels.Serialize(false) + ep.Labels[endpoint.AWSSDDescriptionLabel] = ep.Labels.SerializePlain(false) } } diff --git a/registry/txt.go b/registry/txt.go index 48dd028d5c..2c7cccbdf2 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -52,15 +52,27 @@ type TXTRegistry struct { // missingTXTRecords stores TXT records which are missing after the migration to the new format missingTXTRecords []*endpoint.Endpoint + + // encrypt text records + txtEncryptEnabled bool + txtEncryptAESKey []byte } const keySuffixAAAA = ":AAAA" // NewTXTRegistry returns new TXTRegistry object -func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID string, cacheInterval time.Duration, txtWildcardReplacement string, managedRecordTypes []string) (*TXTRegistry, error) { +func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID string, cacheInterval time.Duration, txtWildcardReplacement string, managedRecordTypes []string, txtEncryptEnabled bool, txtEncryptAESKey []byte) (*TXTRegistry, error) { if ownerID == "" { return nil, errors.New("owner id cannot be empty") } + if len(txtEncryptAESKey) == 0 { + txtEncryptAESKey = nil + } else if len(txtEncryptAESKey) != 32 { + return nil, errors.New("the AES Encryption key must have a length of 32 bytes") + } + if txtEncryptEnabled && txtEncryptAESKey == nil { + return nil, errors.New("the AES Encryption key must be set when TXT record encryption is enabled") + } if len(txtPrefix) > 0 && len(txtSuffix) > 0 { return nil, errors.New("txt-prefix and txt-suffix are mutual exclusive") @@ -75,6 +87,8 @@ func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID st cacheInterval: cacheInterval, wildcardReplacement: txtWildcardReplacement, managedRecordTypes: managedRecordTypes, + txtEncryptEnabled: txtEncryptEnabled, + txtEncryptAESKey: txtEncryptAESKey, }, nil } @@ -114,7 +128,7 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error continue } // We simply assume that TXT records for the registry will always have only one target. - labels, err := endpoint.NewLabelsFromString(record.Targets[0]) + labels, err := endpoint.NewLabelsFromString(record.Targets[0], im.txtEncryptAESKey) if err == endpoint.ErrInvalidHeritage { // if no heritage is found or it is invalid // case when value of txt record cannot be identified @@ -205,7 +219,7 @@ func (im *TXTRegistry) generateTXTRecord(r *endpoint.Endpoint) []*endpoint.Endpo if r.RecordType != endpoint.RecordTypeAAAA { // old TXT record format - txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true, im.txtEncryptEnabled, im.txtEncryptAESKey)) if txt != nil { txt.WithSetIdentifier(r.SetIdentifier) txt.Labels[endpoint.OwnedRecordLabelKey] = r.DNSName @@ -213,9 +227,8 @@ func (im *TXTRegistry) generateTXTRecord(r *endpoint.Endpoint) []*endpoint.Endpo endpoints = append(endpoints, txt) } } - // new TXT record format (containing record type) - txtNew := endpoint.NewEndpoint(im.mapper.toNewTXTName(r.DNSName, r.RecordType), endpoint.RecordTypeTXT, r.Labels.Serialize(true)) + txtNew := endpoint.NewEndpoint(im.mapper.toNewTXTName(r.DNSName, r.RecordType), endpoint.RecordTypeTXT, r.Labels.Serialize(true, im.txtEncryptEnabled, im.txtEncryptAESKey)) if txtNew != nil { txtNew.WithSetIdentifier(r.SetIdentifier) txtNew.Labels[endpoint.OwnedRecordLabelKey] = r.DNSName diff --git a/registry/txt_test.go b/registry/txt_test.go index 2f7297fb11..80075c81d1 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -46,20 +46,20 @@ func TestTXTRegistry(t *testing.T) { func testTXTRegistryNew(t *testing.T) { p := inmemory.NewInMemoryProvider() - _, err := NewTXTRegistry(p, "txt", "", "", time.Hour, "", []string{}) + _, err := NewTXTRegistry(p, "txt", "", "", time.Hour, "", []string{}, false, nil) require.Error(t, err) - _, err = NewTXTRegistry(p, "", "txt", "", time.Hour, "", []string{}) + _, err = NewTXTRegistry(p, "", "txt", "", time.Hour, "", []string{}, false, nil) require.Error(t, err) - r, err := NewTXTRegistry(p, "txt", "", "owner", time.Hour, "", []string{}) + r, err := NewTXTRegistry(p, "txt", "", "owner", time.Hour, "", []string{}, false, nil) require.NoError(t, err) assert.Equal(t, p, r.provider) - r, err = NewTXTRegistry(p, "", "txt", "owner", time.Hour, "", []string{}) + r, err = NewTXTRegistry(p, "", "txt", "owner", time.Hour, "", []string{}, false, nil) require.NoError(t, err) - _, err = NewTXTRegistry(p, "txt", "txt", "owner", time.Hour, "", []string{}) + _, err = NewTXTRegistry(p, "txt", "txt", "owner", time.Hour, "", []string{}, false, nil) require.Error(t, err) _, ok := r.mapper.(affixNameMapper) @@ -67,7 +67,17 @@ func testTXTRegistryNew(t *testing.T) { assert.Equal(t, "owner", r.ownerID) assert.Equal(t, p, r.provider) - r, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + aesKey := []byte(";k&l)nUC/33:{?d{3)54+,AD?]SX%yh^") + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) + require.NoError(t, err) + + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, aesKey) + require.NoError(t, err) + + _, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, true, nil) + require.Error(t, err) + + r, err = NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, true, aesKey) require.NoError(t, err) _, ok = r.mapper.(affixNameMapper) @@ -203,13 +213,13 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{}) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) // Ensure prefix is case-insensitive - r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "", []string{}) + r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "", []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpointLabels(records, expectedRecords)) @@ -328,13 +338,13 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) // Ensure prefix is case-insensitive - r, _ = NewTXTRegistry(p, "", "-TxT", "owner", time.Hour, "", []string{}) + r, _ = NewTXTRegistry(p, "", "-TxT", "owner", time.Hour, "", []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpointLabels(records, expectedRecords)) @@ -429,7 +439,7 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) records, _ := r.Records(ctx) assert.True(t, testutils.SameEndpoints(records, expectedRecords)) @@ -472,7 +482,7 @@ func testTXTRegistryApplyChangesWithPrefix(t *testing.T) { newEndpointWithOwner("txt.cname-multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -561,7 +571,7 @@ func testTXTRegistryApplyChangesWithTemplatedPrefix(t *testing.T) { p.ApplyChanges(ctx, &plan.Changes{ Create: []*endpoint.Endpoint{}, }) - r, _ := NewTXTRegistry(p, "prefix%{record_type}.", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "prefix%{record_type}.", "", "owner", time.Hour, "", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", endpoint.RecordTypeCNAME, "", "ingress/default/my-ingress"), @@ -605,7 +615,7 @@ func testTXTRegistryApplyChangesWithTemplatedSuffix(t *testing.T) { p.OnApplyChanges = func(ctx context.Context, got *plan.Changes) { assert.Equal(t, ctxEndpoints, ctx.Value(provider.RecordsContextKey)) } - r, _ := NewTXTRegistry(p, "", "-%{record_type}suffix", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "-%{record_type}suffix", "owner", time.Hour, "", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ newEndpointWithOwnerResource("new-record-1.test-zone.example.org", "new-loadbalancer-1.lb.com", endpoint.RecordTypeCNAME, "", "ingress/default/my-ingress"), @@ -671,7 +681,7 @@ func testTXTRegistryApplyChangesWithSuffix(t *testing.T) { newEndpointWithOwner("cname-multiple-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"), }, }) - r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "wildcard", []string{}) + r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "wildcard", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -775,7 +785,7 @@ func testTXTRegistryApplyChangesNoPrefix(t *testing.T) { newEndpointWithOwner("cname-foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -941,7 +951,7 @@ func testTXTRegistryMissingRecordsNoPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) records, _ := r.Records(ctx) missingRecords := r.MissingRecords() @@ -1045,7 +1055,7 @@ func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { }, } - r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}) + r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) records, _ := r.Records(ctx) missingRecords := r.MissingRecords() @@ -1199,7 +1209,7 @@ func TestNewTXTScheme(t *testing.T) { newEndpointWithOwner("cname-foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""), }, }) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) changes := &plan.Changes{ Create: []*endpoint.Endpoint{ @@ -1275,7 +1285,7 @@ func TestGenerateTXT(t *testing.T) { } p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) gotTXT := r.generateTXTRecord(record) assert.Equal(t, expectedTXT, gotTXT) } @@ -1294,7 +1304,7 @@ func TestGenerateTXTForAAAA(t *testing.T) { } p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) gotTXT := r.generateTXTRecord(record) assert.Equal(t, expectedTXT, gotTXT) } @@ -1311,7 +1321,7 @@ func TestFailGenerateTXT(t *testing.T) { expectedTXT := []*endpoint.Endpoint{} p := inmemory.NewInMemoryProvider() p.CreateZone(testZone) - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}) + r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{}, false, nil) gotTXT := r.generateTXTRecord(cnameRecord) assert.Equal(t, expectedTXT, gotTXT) } From bbce4a843eb7d310dd94f49bee67cb25ee0e274c Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Tue, 21 Feb 2023 07:27:17 +0100 Subject: [PATCH 045/154] chore: godaddy s/Discard/Ignore/g - its confusing --- provider/godaddy/godaddy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/godaddy/godaddy.go b/provider/godaddy/godaddy.go index 76b0520766..556cacd4d5 100644 --- a/provider/godaddy/godaddy.go +++ b/provider/godaddy/godaddy.go @@ -247,7 +247,7 @@ func (p *GDProvider) records(ctx *context.Context, zone string, all bool) (*gdRe results.records = append(results.records, rec) } else { - log.Infof("GoDaddy: Discard record %s for %s is %+v", rec.Name, zone, rec) + log.Infof("GoDaddy: Ignore record %s for %s is %+v", rec.Name, zone, rec) } } From f5692478829ddf1e06829e4f518d4dea735a5dde Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Tue, 21 Feb 2023 07:26:26 +0100 Subject: [PATCH 046/154] fix: godaddy add ratelimit backoff --- provider/godaddy/client.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/provider/godaddy/client.go b/provider/godaddy/client.go index 32f4df62c3..e70589cc5b 100644 --- a/provider/godaddy/client.go +++ b/provider/godaddy/client.go @@ -23,9 +23,12 @@ import ( "errors" "fmt" "io" + "math/rand" "net/http" + "strconv" "time" + "golang.org/x/time/rate" "sigs.k8s.io/external-dns/pkg/apis/externaldns" ) @@ -71,6 +74,9 @@ type Client struct { // Client is the underlying HTTP client used to run the requests. It may be overloaded but a default one is instanciated in ``NewClient`` by default. Client *http.Client + // GoDaddy limits to 60 requests per minute + Ratelimiter *rate.Limiter + // Logger is used to log HTTP requests and responses. Logger Logger @@ -115,6 +121,7 @@ func NewClient(useOTE bool, apiKey, apiSecret string) (*Client, error) { APISecret: apiSecret, APIEndPoint: endpoint, Client: &http.Client{}, + Ratelimiter: rate.NewLimiter(rate.Every(60*time.Second), 60), Timeout: DefaultTimeout, } @@ -216,7 +223,22 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) { if c.Logger != nil { c.Logger.LogRequest(req) } + + c.Ratelimiter.Wait(req.Context()) resp, err := c.Client.Do(req) + // In case of several clients behind NAT we still can hit rate limit + for i := 1; i < 3 && err == nil && resp.StatusCode == 429; i++ { + retryAfter, _ := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 0) + + jitter := rand.Int63n(int64(retryAfter)) + retryAfterSec := retryAfter + jitter/2 + + sleepTime := time.Duration(retryAfterSec) * time.Second + time.Sleep(sleepTime) + + c.Ratelimiter.Wait(req.Context()) + resp, err = c.Client.Do(req) + } if err != nil { return nil, err } From 7a452014167aaf05351bbd84de8c5d1b8acdfe7d Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Tue, 21 Feb 2023 06:44:17 +0100 Subject: [PATCH 047/154] fix: godaddy #2467 update 2nd level records fix: godaddy 'update' use corrent api uri --- provider/godaddy/godaddy.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/provider/godaddy/godaddy.go b/provider/godaddy/godaddy.go index 556cacd4d5..ef4e4776e2 100644 --- a/provider/godaddy/godaddy.go +++ b/provider/godaddy/godaddy.go @@ -86,6 +86,7 @@ type gdUpdateRecordField struct { Data string `json:"data"` Name string `json:"name"` TTL int64 `json:"ttl"` + Type string `json:"type"` Port *int `json:"port,omitempty"` Priority *int `json:"priority,omitempty"` Weight *int64 `json:"weight,omitempty"` @@ -347,6 +348,9 @@ func (p *GDProvider) changeAllRecords(endpoints []gdEndpoint, zoneRecords []*gdR log.Debugf("Skipping record %s because no hosted zone matching record DNS Name was detected", dnsName) } else { dnsName = strings.TrimSuffix(dnsName, "."+zone) + if dnsName == zone { + dnsName = "" + } if e.endpoint.RecordType == endpoint.RecordTypeA && (len(dnsName) == 0) { dnsName = "@" @@ -397,7 +401,7 @@ func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) er allChanges = p.appendChange(gdDelete, changes.Delete, allChanges) allChanges = p.appendChange(gdDelete, changes.UpdateOld, allChanges) - allChanges = p.appendChange(gdCreate, changes.UpdateNew, allChanges) + allChanges = p.appendChange(gdUpdate, changes.UpdateNew, allChanges) allChanges = p.appendChange(gdCreate, changes.Create, allChanges) log.Infof("GoDaddy: %d changes will be done", len(allChanges)) @@ -442,6 +446,7 @@ func (p *gdRecords) updateRecord(client gdClient, change gdRecordField, dryRun b Data: change.Data, Name: change.Name, TTL: change.TTL, + Type: change.Type, Port: change.Port, Priority: change.Priority, Weight: change.Weight, @@ -451,7 +456,7 @@ func (p *gdRecords) updateRecord(client gdClient, change gdRecordField, dryRun b if dryRun { log.Infof("[DryRun] - Update record %s.%s of type %s %s", change.Name, p.zone, change.Type, toString(changed)) - } else if err := client.Patch(fmt.Sprintf("/v1/domains/%s/records/%s", p.zone, change.Type), changed, &response); err != nil { + } else if err := client.Patch(fmt.Sprintf("/v1/domains/%s/records", p.zone), changed, &response); err != nil { log.Errorf("Update record %s.%s of type %s failed: %v", change.Name, p.zone, change.Type, response) return err @@ -488,7 +493,11 @@ func (p *gdRecords) deleteRecord(client gdClient, change gdRecordField, dryRun b } else if err := client.Delete(fmt.Sprintf("/v1/domains/%s/records/%s/%s", p.zone, change.Type, change.Name), &response); err != nil { log.Errorf("Delete record %s.%s of type %s failed: %v", change.Name, p.zone, change.Type, response) - return err + if strings.Contains(err.Error(), "RECORD_NOT_FOUND") { + log.Debugf("Handle not found - already deleted?") + } else { + return err + } } } else { log.Warnf("GoDaddy: record in zone %s not found %s to delete", p.zone, change.String()) From 36409bb0fc5be69124edf10943d0ad937b3a88be Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Fri, 3 Mar 2023 17:54:12 +0100 Subject: [PATCH 048/154] fix: godaddy - use right methods to add/delete/update --- provider/godaddy/godaddy.go | 229 ++++++++++++++++++++++-------------- 1 file changed, 141 insertions(+), 88 deletions(-) diff --git a/provider/godaddy/godaddy.go b/provider/godaddy/godaddy.go index ef4e4776e2..2193e5c278 100644 --- a/provider/godaddy/godaddy.go +++ b/provider/godaddy/godaddy.go @@ -34,13 +34,13 @@ import ( const ( gdMinimalTTL = 600 gdCreate = 0 - gdUpdate = 1 + gdReplace = 1 gdDelete = 2 ) var actionNames = []string{ "create", - "update", + "replace", "delete", } @@ -82,11 +82,9 @@ type gdRecordField struct { Service *string `json:"service,omitempty"` } -type gdUpdateRecordField struct { +type gdReplaceRecordField struct { Data string `json:"data"` - Name string `json:"name"` TTL int64 `json:"ttl"` - Type string `json:"type"` Port *int `json:"port,omitempty"` Priority *int `json:"priority,omitempty"` Weight *int64 `json:"weight,omitempty"` @@ -356,23 +354,12 @@ func (p *GDProvider) changeAllRecords(endpoints []gdEndpoint, zoneRecords []*gdR dnsName = "@" } - for _, target := range e.endpoint.Targets { - change := gdRecordField{ - Type: e.endpoint.RecordType, - Name: dnsName, - TTL: p.ttl, - Data: target, - } - - if e.endpoint.RecordTTL.IsConfigured() { - change.TTL = maxOf(gdMinimalTTL, int64(e.endpoint.RecordTTL)) - } + e.endpoint.RecordTTL = endpoint.TTL(maxOf(gdMinimalTTL, int64(e.endpoint.RecordTTL))) - if err := zoneRecord.applyChange(e.action, p.client, change, p.DryRun); err != nil { - log.Errorf("Unable to apply change %s on record %s, %v", actionNames[e.action], change, err) + if err := zoneRecord.applyEndpoint(e.action, p.client, *e.endpoint, dnsName, p.DryRun); err != nil { + log.Errorf("Unable to apply change %s on record %s type %s, %v", actionNames[e.action], dnsName, e.endpoint.RecordType, err) - return err - } + return err } } } @@ -380,6 +367,22 @@ func (p *GDProvider) changeAllRecords(endpoints []gdEndpoint, zoneRecords []*gdR return nil } +func (p *GDProvider) endpointEqual(l *endpoint.Endpoint, r *endpoint.Endpoint) bool { + if l.DNSName != r.DNSName || l.RecordType!= r.RecordType { + return false + } + + if ! l.Targets.Same(r.Targets) { + return false + } + + if l.RecordTTL != r.RecordTTL { + return false + } + + return true +} + // ApplyChanges applies a given set of changes in a given zone. func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { if countTargets(changes) == 0 { @@ -397,11 +400,29 @@ func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) er changedZoneRecords[i] = &records[i] } - allChanges := make([]gdEndpoint, 0, countTargets(changes)) + var allChanges []gdEndpoint allChanges = p.appendChange(gdDelete, changes.Delete, allChanges) - allChanges = p.appendChange(gdDelete, changes.UpdateOld, allChanges) - allChanges = p.appendChange(gdUpdate, changes.UpdateNew, allChanges) + + for _, recOld := range changes.UpdateOld { + for _, recNew := range changes.UpdateNew { + if recOld.DNSName != recNew.DNSName { + continue + } + + if ! p.endpointEqual(recOld, recNew) { + DeleteEndpoints := []*endpoint.Endpoint{recOld} + PatchEndpoints := []*endpoint.Endpoint{recNew} + if recOld.RecordType == recNew.RecordType { + allChanges = p.appendChange(gdReplace, PatchEndpoints, allChanges) + } else { + allChanges = p.appendChange(gdDelete, DeleteEndpoints, allChanges) + allChanges = p.appendChange(gdCreate, PatchEndpoints, allChanges) + } + } + } + } + allChanges = p.appendChange(gdCreate, changes.Create, allChanges) log.Infof("GoDaddy: %d changes will be done", len(allChanges)) @@ -413,107 +434,139 @@ func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) er return nil } -func (p *gdRecords) addRecord(client gdClient, change gdRecordField, dryRun bool) error { +func (p *gdRecords) addRecord(client gdClient, endpoint endpoint.Endpoint, dnsName string, dryRun bool) error { var response GDErrorResponse + for _, target := range endpoint.Targets { + change := gdRecordField{ + Type: endpoint.RecordType, + Name: dnsName, + TTL: int64(endpoint.RecordTTL), + Data: target, + } - log.Debugf("GoDaddy: Add an entry %s to zone %s", change.String(), p.zone) + p.records = append(p.records, change) + p.changed = true - p.records = append(p.records, change) - p.changed = true + log.Debugf("GoDaddy: Add an entry %s to zone %s", change.String(), p.zone) + if dryRun { + log.Infof("[DryRun] - Add record %s.%s of type %s %s", change.Name, p.zone, change.Type, toString(change)) + } else if err := client.Patch(fmt.Sprintf("/v1/domains/%s/records", p.zone), []gdRecordField{change}, &response); err != nil { + log.Errorf("Add record %s.%s of type %s failed: %s", change.Name, p.zone, change.Type, response) - if dryRun { - log.Infof("[DryRun] - Add record %s.%s of type %s %s", change.Name, p.zone, change.Type, toString(change)) - } else if err := client.Patch(fmt.Sprintf("/v1/domains/%s/records", p.zone), []gdRecordField{change}, &response); err != nil { - log.Errorf("Add record %s.%s of type %s failed: %s", change.Name, p.zone, change.Type, response) + return err + } - return err } return nil } -func (p *gdRecords) updateRecord(client gdClient, change gdRecordField, dryRun bool) error { - log.Debugf("GoDaddy: Update an entry %s to zone %s", change.String(), p.zone) - - for index, record := range p.records { - if record.Type == change.Type && record.Name == change.Name { - var response GDErrorResponse - - p.records[index] = change - p.changed = true +func (p *gdRecords) replaceRecord(client gdClient, endpoint endpoint.Endpoint, dnsName string, dryRun bool) error { + changed := []gdReplaceRecordField{} + records := []string{} - changed := []gdUpdateRecordField{{ - Data: change.Data, - Name: change.Name, - TTL: change.TTL, - Type: change.Type, - Port: change.Port, - Priority: change.Priority, - Weight: change.Weight, - Protocol: change.Protocol, - Service: change.Service, - }} - - if dryRun { - log.Infof("[DryRun] - Update record %s.%s of type %s %s", change.Name, p.zone, change.Type, toString(changed)) - } else if err := client.Patch(fmt.Sprintf("/v1/domains/%s/records", p.zone), changed, &response); err != nil { - log.Errorf("Update record %s.%s of type %s failed: %v", change.Name, p.zone, change.Type, response) + for _, target := range endpoint.Targets { + change := gdRecordField{ + Type: endpoint.RecordType, + Name: dnsName, + TTL: int64(endpoint.RecordTTL), + Data: target, + } - return err + for index, record := range p.records { + if record.Type == change.Type && record.Name == change.Name { + p.records[index] = change + p.changed = true } } + records = append(records, target) + changed = append(changed, gdReplaceRecordField{ + Data: change.Data, + TTL: change.TTL, + Port: change.Port, + Priority: change.Priority, + Weight: change.Weight, + Protocol: change.Protocol, + Service: change.Service, + }) + } + + var response GDErrorResponse + + + if dryRun { + log.Infof("[DryRun] - Replace record %s.%s of type %s %s", dnsName, p.zone, endpoint.RecordType, records) + + return nil + } + + log.Debugf("Replace record %s.%s of type %s %s", dnsName, p.zone, endpoint.RecordType, records) + if err := client.Put(fmt.Sprintf("/v1/domains/%s/records/%s/%s", p.zone, endpoint.RecordType, dnsName), changed, &response); err != nil { + log.Errorf("Replace record %s.%s of type %s failed: %v", dnsName, p.zone, endpoint.RecordType, response) + + return err } return nil } // Remove one record from the record list -func (p *gdRecords) deleteRecord(client gdClient, change gdRecordField, dryRun bool) error { - log.Debugf("GoDaddy: Delete an entry %s to zone %s", change.String(), p.zone) +func (p *gdRecords) deleteRecord(client gdClient, endpoint endpoint.Endpoint, dnsName string, dryRun bool) error { + records := []string{} + + for _, target := range endpoint.Targets { + change := gdRecordField{ + Type: endpoint.RecordType, + Name: dnsName, + TTL: int64(endpoint.RecordTTL), + Data: target, + } + records = append(records, target) - deleteIndex := -1 + log.Debugf("GoDaddy: Delete an entry %s from zone %s", change.String(), p.zone) - for index, record := range p.records { - if record.Type == change.Type && record.Name == change.Name && record.Data == change.Data { - deleteIndex = index - break + deleteIndex := -1 + + for index, record := range p.records { + if record.Type == change.Type && record.Name == change.Name && record.Data == change.Data { + deleteIndex = index + break + } } - } - if deleteIndex >= 0 { - var response GDErrorResponse + if deleteIndex >= 0 { + p.records[deleteIndex] = p.records[len(p.records)-1] - p.records[deleteIndex] = p.records[len(p.records)-1] + p.records = p.records[:len(p.records)-1] + p.changed = true + } - p.records = p.records[:len(p.records)-1] - p.changed = true + } - if dryRun { - log.Infof("[DryRun] - Delete record %s.%s of type %s %s", change.Name, p.zone, change.Type, toString(change)) - } else if err := client.Delete(fmt.Sprintf("/v1/domains/%s/records/%s/%s", p.zone, change.Type, change.Name), &response); err != nil { - log.Errorf("Delete record %s.%s of type %s failed: %v", change.Name, p.zone, change.Type, response) + if dryRun { + log.Infof("[DryRun] - Delete record %s.%s of type %s %s", dnsName, p.zone, endpoint.RecordType, records) - if strings.Contains(err.Error(), "RECORD_NOT_FOUND") { - log.Debugf("Handle not found - already deleted?") - } else { - return err - } - } - } else { - log.Warnf("GoDaddy: record in zone %s not found %s to delete", p.zone, change.String()) + return nil + } + + var response GDErrorResponse + if err := client.Delete(fmt.Sprintf("/v1/domains/%s/records/%s/%s", p.zone, endpoint.RecordType, dnsName), &response); err != nil { + log.Errorf("Delete record %s.%s of type %s failed: %v", dnsName, p.zone, endpoint.RecordType, response) + + return err } return nil } -func (p *gdRecords) applyChange(action int, client gdClient, change gdRecordField, dryRun bool) error { +func (p *gdRecords) applyEndpoint(action int, client gdClient, endpoint endpoint.Endpoint, dnsName string, dryRun bool) error { switch action { case gdCreate: - return p.addRecord(client, change, dryRun) - case gdUpdate: - return p.updateRecord(client, change, dryRun) + return p.addRecord(client, endpoint, dnsName, dryRun) + case gdReplace: + return p.replaceRecord(client, endpoint, dnsName, dryRun) case gdDelete: - return p.deleteRecord(client, change, dryRun) + return p.deleteRecord(client, endpoint, dnsName, dryRun) } return nil From e233a2accb963472a38b1ec0ec0bcd5fcd20d848 Mon Sep 17 00:00:00 2001 From: Houssem Dellai Date: Mon, 1 May 2023 11:57:54 +0200 Subject: [PATCH 049/154] Added video tutorial in azure.md for using Azure DNS --- docs/tutorials/azure.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/tutorials/azure.md b/docs/tutorials/azure.md index 186407aaae..b6d8850340 100644 --- a/docs/tutorials/azure.md +++ b/docs/tutorials/azure.md @@ -648,3 +648,9 @@ resource group: ```bash $ az group delete --name "MyDnsResourceGroup" ``` + +## More tutorials + +A video explanantion is available here: https://www.youtube.com/watch?v=VSn6DPKIhM8&list=PLpbcUe4chE79sB7Jg7B4z3HytqUUEwcNE + +![image](https://user-images.githubusercontent.com/6548359/235437721-87611869-75f2-4f32-bb35-9da585e46299.png) From 4e9dcd096695f7f158c3f3ed4cc63f0cb6ecf118 Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 2 May 2023 16:00:07 +0100 Subject: [PATCH 050/154] Update docs --- README.md | 1 + docs/tutorials/mx-record.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 docs/tutorials/mx-record.md diff --git a/README.md b/README.md index a5041afbed..13c7f4b545 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ The following tutorials are provided: * [Nginx Ingress Controller](docs/tutorials/nginx-ingress.md) * [NS1](docs/tutorials/ns1.md) * [NS Record Creation with CRD Source](docs/tutorials/ns-record.md) +* [MX Record Creation with CRD Source](docs/tutorials/mx-record.md) * [OpenStack Designate](docs/tutorials/designate.md) * [Oracle Cloud Infrastructure (OCI) DNS](docs/tutorials/oracle.md) * [PowerDNS](docs/tutorials/pdns.md) diff --git a/docs/tutorials/mx-record.md b/docs/tutorials/mx-record.md new file mode 100644 index 0000000000..5b5a0eb0b2 --- /dev/null +++ b/docs/tutorials/mx-record.md @@ -0,0 +1,28 @@ +# Creating MX record with CRD source + +You can create and manage MX records with the help of [CRD source](/docs/contributing/crd-source.md) +and `DNSEndpoint` CRD. Currently, this feature is only supported by `aws`, `azure`, and `google` providers. + +In order to start managing MX records you need to set the `--managed-record-types MX` flag. + +```console +external-dns --source crd --provider {aws|azure|google} --managed-record-types A --managed-record-types CNAME --managed-record-types MX +``` + +Targets within the CRD need to be specified according to the RFC 1034 (section 3.6.1). Below is an example of +`example.com` DNS MX record which specifies two separate targets with distinct priorities. + +```yaml +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: examplemxrecord +spec: + endpoints: + - dnsName: example.com + recordTTL: 180 + recordType: MX + targets: + - 10 mailhost1.example.com + - 20 mailhost2.example.com +``` From 93665c9e7475a7202c74be05fd8af85bf217c0bc Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 2 May 2023 16:01:59 +0100 Subject: [PATCH 051/154] Update nolint comments --- provider/azure/azure.go | 2 +- provider/azure/azure_private_dns.go | 2 +- provider/azure/common.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/provider/azure/azure.go b/provider/azure/azure.go index 24a0e0ecbe..b56a21320a 100644 --- a/provider/azure/azure.go +++ b/provider/azure/azure.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// nolint:staticcheck +//nolint:staticcheck // Required due to the current dependency on a deprecated version of azure-sdk-for-go package azure import ( diff --git a/provider/azure/azure_private_dns.go b/provider/azure/azure_private_dns.go index fd5733bfe1..e3ab40c48e 100644 --- a/provider/azure/azure_private_dns.go +++ b/provider/azure/azure_private_dns.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// nolint:staticcheck +//nolint:staticcheck // Required due to the current dependency on a deprecated version of azure-sdk-for-go package azure import ( diff --git a/provider/azure/common.go b/provider/azure/common.go index e6c45ece20..95fd1a8515 100644 --- a/provider/azure/common.go +++ b/provider/azure/common.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// nolint:staticcheck +//nolint:staticcheck // Required due to the current dependency on a deprecated version of azure-sdk-for-go package azure import ( From 2533415e24975ed1a04391b00f5f3b4cc389124f Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 2 May 2023 17:28:43 +0100 Subject: [PATCH 052/154] Add tests for AWS --- provider/aws/aws_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 362ebb989a..91ceb8a188 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -356,6 +356,7 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, "NY"), endpoint.NewEndpoint("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), + endpoint.NewEndpointWithTTL("mail.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), }) records, err := provider.Records(context.Background()) @@ -380,6 +381,7 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, "NY"), endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), + endpoint.NewEndpointWithTTL("mail.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), }) } @@ -419,6 +421,7 @@ func TestAWSCreateRecords(t *testing.T) { endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpoint("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.example.com", "20 mailhost2.example.com"), } require.NoError(t, provider.CreateRecords(context.Background(), records)) @@ -434,6 +437,7 @@ func TestAWSCreateRecords(t *testing.T) { endpoint.NewEndpointWithTTL("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpointWithTTL("create-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpointWithTTL("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), }) } @@ -444,6 +448,7 @@ func TestAWSUpdateRecords(t *testing.T) { endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com"), }) currentRecords := []*endpoint.Endpoint{ @@ -452,6 +457,7 @@ func TestAWSUpdateRecords(t *testing.T) { endpoint.NewEndpoint("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.1.1.1"), endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com"), } updatedRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"), @@ -459,6 +465,7 @@ func TestAWSUpdateRecords(t *testing.T) { endpoint.NewEndpoint("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "bar.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpoint("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), } require.NoError(t, provider.UpdateRecords(context.Background(), updatedRecords, currentRecords)) @@ -472,6 +479,7 @@ func TestAWSUpdateRecords(t *testing.T) { endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), }) } @@ -484,6 +492,7 @@ func TestAWSDeleteRecords(t *testing.T) { endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("delete-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "delete-test.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificTargetHostedZone, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), endpoint.NewEndpointWithTTL("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), } provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), false, false, originalEndpoints) @@ -531,6 +540,8 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpointWithTTL("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpointWithTTL("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("before").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpointWithTTL("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "10"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost2.bar.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "30 mailhost1.foo.elb.amazonaws.com"), }) createRecords := []*endpoint.Endpoint{ @@ -539,6 +550,7 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpoint("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com"), } currentRecords := []*endpoint.Endpoint{ @@ -554,6 +566,7 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpoint("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpoint("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("before").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpoint("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "10"), + endpoint.NewEndpoint("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost2.bar.elb.amazonaws.com"), } updatedRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"), @@ -568,6 +581,7 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpoint("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificRegion, "us-east-1"), endpoint.NewEndpoint("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("after").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpoint("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "20"), + endpoint.NewEndpoint("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "20 mailhost3.foo.elb.amazonaws.com"), } deleteRecords := []*endpoint.Endpoint{ @@ -576,6 +590,7 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"), endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"), endpoint.NewEndpoint("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpoint("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "30 mailhost1.foo.elb.amazonaws.com"), } changes := &plan.Changes{ @@ -616,6 +631,8 @@ func TestAWSApplyChanges(t *testing.T) { endpoint.NewEndpointWithTTL("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificRegion, "us-east-1"), endpoint.NewEndpointWithTTL("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("after").WithProviderSpecific(providerSpecificWeight, "10"), endpoint.NewEndpointWithTTL("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "20"), + endpoint.NewEndpointWithTTL("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mailhost3.foo.elb.amazonaws.com"), }) } } @@ -633,6 +650,8 @@ func TestAWSApplyChangesDryRun(t *testing.T) { endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), endpoint.NewEndpointWithTTL("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mail.foo.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mail.bar.elb.amazonaws.com"), } provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, true, originalEndpoints) @@ -643,6 +662,7 @@ func TestAWSApplyChangesDryRun(t *testing.T) { endpoint.NewEndpoint("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.elb.amazonaws.com"), endpoint.NewEndpoint("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "30 mail.foo.elb.amazonaws.com"), } currentRecords := []*endpoint.Endpoint{ @@ -652,6 +672,7 @@ func TestAWSApplyChangesDryRun(t *testing.T) { endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "bar.elb.amazonaws.com"), endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "bar.elb.amazonaws.com"), endpoint.NewEndpoint("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "20 mail.foo.elb.amazonaws.com"), } updatedRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"), @@ -660,6 +681,7 @@ func TestAWSApplyChangesDryRun(t *testing.T) { endpoint.NewEndpoint("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "baz.elb.amazonaws.com"), endpoint.NewEndpoint("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "baz.elb.amazonaws.com"), endpoint.NewEndpoint("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpoint("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mail.bar.elb.amazonaws.com"), } deleteRecords := []*endpoint.Endpoint{ @@ -668,6 +690,7 @@ func TestAWSApplyChangesDryRun(t *testing.T) { endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"), endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "qux.elb.amazonaws.com"), endpoint.NewEndpoint("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpoint("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mail.bar.elb.amazonaws.com"), } changes := &plan.Changes{ From 4a2b9c60aba171f2c409150308ed134a80652473 Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Thu, 4 May 2023 15:10:27 +0200 Subject: [PATCH 053/154] ingress: improve ingress class name filter testing Signed-off-by: Arnaud Lefray --- source/ingress.go | 7 ++- source/ingress_test.go | 96 +++++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 21 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index 56833e15c1..bf204a2667 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -45,6 +45,8 @@ const ( // Possible values for the ingress-hostname-source annotation IngressHostnameSourceAnnotationOnlyValue = "annotation-only" IngressHostnameSourceDefinedHostsOnlyValue = "defined-hosts-only" + + IngressClassAnnotationKey = "kubernetes.io/ingress.class" ) // ingressSource is an implementation of Source for Kubernetes ingress objects. @@ -238,11 +240,11 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] // class func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([]*networkv1.Ingress, error) { // if no class filter is specified then there's nothing to do - if sc.ingressClassNames == nil { + if len(sc.ingressClassNames) == 0 { return ingresses, nil } - classNameReq, err := labels.NewRequirement("kubernetes.io/ingress.class", selection.In, sc.ingressClassNames) + classNameReq, err := labels.NewRequirement(IngressClassAnnotationKey, selection.In, sc.ingressClassNames) if err != nil { return nil, err } @@ -258,6 +260,7 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ for _, nameFilter := range sc.ingressClassNames { if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { matched = true + } else if matchLabelSelector(selector, ingress.Annotations) { matched = true } diff --git a/source/ingress_test.go b/source/ingress_test.go index a3bfc457af..8d3ae41757 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -136,15 +136,15 @@ func TestNewIngressSource(t *testing.T) { annotationFilter: "kubernetes.io/ingress.class=nginx", }, { - title: "non-empty ingress class name list", - expectError: false, + title: "non-empty ingress class name list", + expectError: false, ingressClassNames: []string{"internal", "external"}, }, { - title: "ingress class name and annotation filter jointly specified", - expectError: true, + title: "ingress class name and annotation filter jointly specified", + expectError: true, ingressClassNames: []string{"internal", "external"}, - annotationFilter: "kubernetes.io/ingress.class=nginx", + annotationFilter: "kubernetes.io/ingress.class=nginx", }, } { ti := ti @@ -378,7 +378,7 @@ func testIngressEndpoints(t *testing.T) { ignoreIngressTLSSpec bool ignoreIngressRulesSpec bool ingressLabelSelector labels.Selector - ingressClassNames []string + ingressClassNames []string }{ { title: "no ingress", @@ -1191,16 +1191,22 @@ func testIngressEndpoints(t *testing.T) { }, }, { - title: "ingressClassName filtering", - targetNamespace: "", - ingressClassNames: []string{"public", "dmz"}, + title: "ingressClassName filtering", + targetNamespace: "", + ingressClassNames: []string{"public", "dmz"}, ingressItems: []fakeIngress{ + { + name: "none", + namespace: namespace, + tlsdnsnames: [][]string{{"none.example.org"}}, + ips: []string{"1.0.0.0"}, + }, { name: "fake-public", namespace: namespace, tlsdnsnames: [][]string{{"example.org"}}, ips: []string{"1.2.3.4"}, - ingressClassName: "public", + ingressClassName: "public", // match }, { name: "fake-internal", @@ -1214,16 +1220,56 @@ func testIngressEndpoints(t *testing.T) { namespace: namespace, tlsdnsnames: [][]string{{"dmz.example.org"}}, ips: []string{"3.4.5.6"}, - ingressClassName: "dmz", + ingressClassName: "dmz", // match }, { - name: "annotated-dmz", - namespace: namespace, - tlsdnsnames: [][]string{{"annodmz.example.org"}}, - ips: []string{"4.5.6.7"}, + name: "annotated-dmz", + namespace: namespace, + tlsdnsnames: [][]string{{"annodmz.example.org"}}, + ips: []string{"4.5.6.7"}, + annotations: map[string]string{ + "kubernetes.io/ingress.class": "dmz", // match + }, + }, + { + name: "fake-internal-annotated-dmz", + namespace: namespace, + tlsdnsnames: [][]string{{"int-annodmz.example.org"}}, + ips: []string{"5.6.7.8"}, + annotations: map[string]string{ + "kubernetes.io/ingress.class": "dmz", // match + }, + ingressClassName: "internal", + }, + { + name: "fake-dmz-annotated-internal", + namespace: namespace, + tlsdnsnames: [][]string{{"dmz-annoint.example.org"}}, + ips: []string{"6.7.8.9"}, + annotations: map[string]string{ + "kubernetes.io/ingress.class": "internal", + }, + ingressClassName: "dmz", // match + }, + { + name: "empty-annotated-dmz", + namespace: namespace, + tlsdnsnames: [][]string{{"empty-annotdmz.example.org"}}, + ips: []string{"7.8.9.0"}, annotations: map[string]string{ - "kubernetes.io/ingress.class": "dmz", + "kubernetes.io/ingress.class": "dmz", // match }, + ingressClassName: "", + }, + { + name: "empty-annotated-internal", + namespace: namespace, + tlsdnsnames: [][]string{{"empty-annotint.example.org"}}, + ips: []string{"8.9.0.1"}, + annotations: map[string]string{ + "kubernetes.io/ingress.class": "internal", + }, + ingressClassName: "", }, }, expected: []*endpoint.Endpoint{ @@ -1239,9 +1285,21 @@ func testIngressEndpoints(t *testing.T) { DNSName: "annodmz.example.org", Targets: endpoint.Targets{"4.5.6.7"}, }, + { + DNSName: "int-annodmz.example.org", + Targets: endpoint.Targets{"5.6.7.8"}, + }, + { + DNSName: "dmz-annoint.example.org", + Targets: endpoint.Targets{"6.7.8.9"}, + }, + { + DNSName: "empty-annotdmz.example.org", + Targets: endpoint.Targets{"7.8.9.0"}, + }, }, - }, - { + }, + { ingressLabelSelector: labels.SelectorFromSet(labels.Set{"app": "web-external"}), title: "ingress with matching labels", targetNamespace: "", @@ -1339,7 +1397,7 @@ func (ing fakeIngress) Ingress() *networkv1.Ingress { Labels: ing.labels, }, Spec: networkv1.IngressSpec{ - Rules: []networkv1.IngressRule{}, + Rules: []networkv1.IngressRule{}, IngressClassName: &ing.ingressClassName, }, Status: networkv1.IngressStatus{ From 04d7ed8ad71aa6ef4aab380836b593996e159e04 Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Thu, 4 May 2023 15:11:50 +0200 Subject: [PATCH 054/154] docs: update class name filtering documentation --- docs/faq.md | 20 ++++++++++---------- docs/tutorials/public-private-route53.md | 5 ++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 10a36422f5..dda8ed9db2 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -258,26 +258,26 @@ Sometimes you need to run an internal and an external dns service. The internal one should provision hostnames used on the internal network (perhaps inside a VPC), and the external one to expose DNS to the internet. -To do this with ExternalDNS you can use the `--ingress-class` to specifically tie an instance of ExternalDNS to -an instance of a ingress controller. Let's assume you have two ingress controllers `nginx-internal` and `nginx-external` -then you can start two ExternalDNS providers one with `--ingress-class=nginx-internal` and one with `--ingress-class=nginx-external`. +To do this with ExternalDNS you can use the `--ingress-class` flag to specifically tie an instance of ExternalDNS to an instance of a ingress controller. +Let's assume you have two ingress controllers, `nginx-internal` and `nginx-external`. +You can then start two ExternalDNS providers, one with `--ingress-class=nginx-internal` and one with `--ingress-class=nginx-external`. -If you need to search for multiple ingress classes, you can specify the argument multiple times, like so: +If you need to search for multiple ingress classes, you can specify the flag multiple times, like so: `--ingress-class=nginx-internal --ingress-class=alb-ingress-internal`. -The `--ingress-class` argument will check both the `ingressClassName` field as well as the deprecated `kubernetes.io/ingress.class` annotation. +The `--ingress-class` flag will check both the `ingressClassName` field and the deprecated `kubernetes.io/ingress.class` annotation. -Note: the `--ingress-class` argument cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. +Note: the `--ingress-class` flag cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. -If you use annotations to indicate different ingress classes in your cluster, you can instead use an `--annotation-filter` argument to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. +If you use annotations to indicate different ingress classes in your cluster, you can instead use an `--annotation-filter` flag to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. However, beware when using annotation filters with multiple sources, e.g. `--source=service --source=ingress`, since `--annotation-filter` will filter every given source objects. If you need to use annotation filters against a specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. **Note:** Filtering based on annotation or ingress class name means that the external-dns controller will receive all resources of that kind and then filter on the client-side. -In larger clusters with many resources which change frequently this can cause performance issues. If only some resources need to be managed by an instance -of external-dns then label filtering can be used instead of annotation filtering. This means that only those resources which match the selector specified -in `--label-filter` will be passed to the controller. +In larger clusters with many resources which change frequently this can cause performance issues. +If only some resources need to be managed by an instance of external-dns then label filtering can be used instead of ingress class filtering (or legacy annotation filtering). +This means that only those resources which match the selector specified in `--label-filter` will be passed to the controller. ### How do I specify that I want the DNS record to point to either the Node's public or private IP when it has both? diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index b8110ecbd2..02ec1a54db 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -351,12 +351,12 @@ metadata: certmanager.k8s.io/acme-challenge-type: "dns01" certmanager.k8s.io/acme-dns01-provider: "route53" certmanager.k8s.io/cluster-issuer: "letsencrypt-production" - kubernetes.io/ingress.class: "external-ingress" kubernetes.io/tls-acme: "true" labels: app: app name: app-public spec: + ingressClassName: "external-ingress" rules: - host: app.domain.com http: @@ -376,12 +376,11 @@ And reuse the requested certificate in private Service definition: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - annotations: - kubernetes.io/ingress.class: "internal-ingress" labels: app: app name: app-private spec: + ingressClassName: "internal-ingress" rules: - host: app.domain.com http: From e9fd86035d1c17a8c8c843a712a7502c6d58a298 Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Thu, 4 May 2023 15:44:14 +0200 Subject: [PATCH 055/154] fix: add missing record check to ingress tests --- source/ingress_test.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source/ingress_test.go b/source/ingress_test.go index dd3a6debc1..b76dd439a4 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -1319,28 +1319,34 @@ func testIngressEndpoints(t *testing.T) { }, expected: []*endpoint.Endpoint{ { - DNSName: "example.org", - Targets: endpoint.Targets{"1.2.3.4"}, + DNSName: "example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"1.2.3.4"}, }, { - DNSName: "dmz.example.org", - Targets: endpoint.Targets{"3.4.5.6"}, + DNSName: "dmz.example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"3.4.5.6"}, }, { - DNSName: "annodmz.example.org", - Targets: endpoint.Targets{"4.5.6.7"}, + DNSName: "annodmz.example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"4.5.6.7"}, }, { - DNSName: "int-annodmz.example.org", - Targets: endpoint.Targets{"5.6.7.8"}, + DNSName: "int-annodmz.example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"5.6.7.8"}, }, { - DNSName: "dmz-annoint.example.org", - Targets: endpoint.Targets{"6.7.8.9"}, + DNSName: "dmz-annoint.example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"6.7.8.9"}, }, { - DNSName: "empty-annotdmz.example.org", - Targets: endpoint.Targets{"7.8.9.0"}, + DNSName: "empty-annotdmz.example.org", + RecordType: endpoint.RecordTypeA, + Targets: endpoint.Targets{"7.8.9.0"}, }, }, }, From e3842a4be60b713d9454ada503c2af45f77d599f Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Fri, 5 May 2023 08:37:12 +0200 Subject: [PATCH 056/154] Apply suggestions from code review Co-authored-by: John Gardiner Myers --- docs/faq.md | 2 +- docs/tutorials/public-private-route53.md | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index cfcc13ba98..527db7ccdb 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -273,7 +273,7 @@ Note: the `--ingress-class` flag cannot be used at the same time as a `kubernete If you use annotations to indicate different ingress classes in your cluster, you can instead use an `--annotation-filter` flag to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. -However, beware when using annotation filters with multiple sources, e.g. `--source=service --source=ingress`, since `--annotation-filter` will filter every given source objects. +However, beware when using annotation filters with multiple sources, e.g. `--source=service --source=ingress`, since `--annotation-filter` will filter every given source object. If you need to use annotation filters against a specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. **Note:** Filtering based on annotation or ingress class name means that the external-dns controller will receive all resources of that kind and then filter on the client-side. diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index 3b950b1094..9ceb431953 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -242,8 +242,6 @@ spec: - --registry=txt - --txt-owner-id=external-dns - --ingress-class=external-ingress - # ... or, if you use annotations for ingress classes - # - --annotation-filter=kubernetes.io/ingress.class in (external-ingress) - --aws-zone-type=public image: registry.k8s.io/external-dns/external-dns:v0.13.4 name: external-dns-public @@ -293,7 +291,7 @@ spec: For this setup to work, you need to create two Ingress definitions for your application. -At first, create public Ingress definition (make sure to un-comment either the `annotations` or `ingressClassName` lines): +At first, create a public Ingress definition (make sure to un-comment either the `annotations` or `ingressClassName` lines): ```yaml apiVersion: networking.k8s.io/v1 @@ -320,7 +318,7 @@ spec: pathType: Prefix ``` -Then create private Ingress definition (again, make sure to un-comment either the `annotations` or `ingressClassName` lines): +Then create a private Ingress definition (again, make sure to un-comment either the `annotations` or `ingressClassName` lines): ```yaml apiVersion: networking.k8s.io/v1 From 42077cd35a2b6ebefaaee60003523291da3639de Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Fri, 5 May 2023 16:08:04 +0200 Subject: [PATCH 057/154] ingress: ignore annotation when ingressclassname is non empty --- source/ingress.go | 7 ++++--- source/ingress_test.go | 9 ++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/ingress.go b/source/ingress.go index bf204a2667..af7a9dc990 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -258,9 +258,10 @@ func (sc *ingressSource) filterByIngressClass(ingresses []*networkv1.Ingress) ([ var matched = false for _, nameFilter := range sc.ingressClassNames { - if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { - matched = true - + if ingress.Spec.IngressClassName != nil && len(*ingress.Spec.IngressClassName) > 0 { + if nameFilter == *ingress.Spec.IngressClassName { + matched = true + } } else if matchLabelSelector(selector, ingress.Annotations) { matched = true } diff --git a/source/ingress_test.go b/source/ingress_test.go index b76dd439a4..2be3eddfd0 100644 --- a/source/ingress_test.go +++ b/source/ingress_test.go @@ -1282,7 +1282,7 @@ func testIngressEndpoints(t *testing.T) { tlsdnsnames: [][]string{{"int-annodmz.example.org"}}, ips: []string{"5.6.7.8"}, annotations: map[string]string{ - "kubernetes.io/ingress.class": "dmz", // match + "kubernetes.io/ingress.class": "dmz", // match but ignored (non-empty ingressClassName) }, ingressClassName: "internal", }, @@ -1302,7 +1302,7 @@ func testIngressEndpoints(t *testing.T) { tlsdnsnames: [][]string{{"empty-annotdmz.example.org"}}, ips: []string{"7.8.9.0"}, annotations: map[string]string{ - "kubernetes.io/ingress.class": "dmz", // match + "kubernetes.io/ingress.class": "dmz", // match (empty ingressClassName) }, ingressClassName: "", }, @@ -1333,11 +1333,6 @@ func testIngressEndpoints(t *testing.T) { RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"4.5.6.7"}, }, - { - DNSName: "int-annodmz.example.org", - RecordType: endpoint.RecordTypeA, - Targets: endpoint.Targets{"5.6.7.8"}, - }, { DNSName: "dmz-annoint.example.org", RecordType: endpoint.RecordTypeA, From f42f3705c5d213a2fed5fdef4abf6c3c736a740e Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Fri, 5 May 2023 16:11:26 +0200 Subject: [PATCH 058/154] docs: replace mentions of ingress.class annotations for the spec.ingressClassName field --- docs/faq.md | 16 +++++++++----- docs/tutorials/alibabacloud.md | 3 +-- .../tutorials/aws-load-balancer-controller.md | 5 +---- docs/tutorials/aws.md | 6 ++--- docs/tutorials/azure-private-dns.md | 3 +-- docs/tutorials/coredns.md | 3 +-- docs/tutorials/exoscale.md | 2 +- docs/tutorials/kube-ingress-aws.md | 5 ----- docs/tutorials/nginx-ingress.md | 4 ---- docs/tutorials/public-private-route53.md | 22 +++++-------------- docs/tutorials/rdns.md | 3 +-- 11 files changed, 25 insertions(+), 47 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 527db7ccdb..adefacb813 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -257,8 +257,7 @@ spec: ### Running an internal and external dns service Sometimes you need to run an internal and an external dns service. -The internal one should provision hostnames used on the internal network (perhaps inside a VPC), and the external -one to expose DNS to the internet. +The internal one should provision hostnames used on the internal network (perhaps inside a VPC), and the external one to expose DNS to the internet. To do this with ExternalDNS you can use the `--ingress-class` flag to specifically tie an instance of ExternalDNS to an instance of a ingress controller. Let's assume you have two ingress controllers, `nginx-internal` and `nginx-external`. @@ -267,16 +266,21 @@ You can then start two ExternalDNS providers, one with `--ingress-class=nginx-in If you need to search for multiple ingress classes, you can specify the flag multiple times, like so: `--ingress-class=nginx-internal --ingress-class=alb-ingress-internal`. -The `--ingress-class` flag will check both the `ingressClassName` field and the deprecated `kubernetes.io/ingress.class` annotation. +The `--ingress-class` flag will check both the `spec.ingressClassName` field and the deprecated `kubernetes.io/ingress.class` annotation. +The `spec.ingressClassName` tasks precedence over the annotation if both are supplied. -Note: the `--ingress-class` flag cannot be used at the same time as a `kubernetes.io/ingress.class` annotation filter; if you do this an error will be raised. +**Backward compatibility** -If you use annotations to indicate different ingress classes in your cluster, you can instead use an `--annotation-filter` flag to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. +The previous `--annotation-filter` flag can still be used to restrict which objects ExternalDNS considers; for example, `--annotation-filter=kubernetes.io/ingress.class in (public,dmz)`. However, beware when using annotation filters with multiple sources, e.g. `--source=service --source=ingress`, since `--annotation-filter` will filter every given source object. If you need to use annotation filters against a specific source you have to run a separated external dns service containing only the wanted `--source` and `--annotation-filter`. -**Note:** Filtering based on annotation or ingress class name means that the external-dns controller will receive all resources of that kind and then filter on the client-side. +Note: the `--ingress-class` flag cannot be used at the same time as the `--annotation-filter=kubernetes.io/ingress.class in (...)` flag; if you do this an error will be raised. + +**Performance considerations** + +Filtering based on ingress class name or annotations means that the external-dns controller will receive all resources of that kind and then filter on the client-side. In larger clusters with many resources which change frequently this can cause performance issues. If only some resources need to be managed by an instance of external-dns then label filtering can be used instead of ingress class filtering (or legacy annotation filtering). This means that only those resources which match the selector specified in `--label-filter` will be passed to the controller. diff --git a/docs/tutorials/alibabacloud.md b/docs/tutorials/alibabacloud.md index ee0477edea..f7653237e4 100644 --- a/docs/tutorials/alibabacloud.md +++ b/docs/tutorials/alibabacloud.md @@ -233,9 +233,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: foo - annotations: - kubernetes.io/ingress.class: "nginx" # use the one that corresponds to your ingress controller. spec: + ingressClassName: nginx # use the one that corresponds to your ingress controller. rules: - host: foo.external-dns-test.com http: diff --git a/docs/tutorials/aws-load-balancer-controller.md b/docs/tutorials/aws-load-balancer-controller.md index 9e66b1e6da..98bc5da693 100644 --- a/docs/tutorials/aws-load-balancer-controller.md +++ b/docs/tutorials/aws-load-balancer-controller.md @@ -24,7 +24,7 @@ as Kubernetes does with the AWS cloud provider. In the examples that follow, it is assumed that you configured the ALB Ingress Controller with the `ingress-class=alb` argument (not to be confused with the same argument to ExternalDNS) so that the controller will only respect Ingress -objects with the `kubernetes.io/ingress.class` annotation set to "alb". +objects with the `ingressClassName` field set to "alb". ## Deploy an example application @@ -80,7 +80,6 @@ kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing - kubernetes.io/ingress.class: alb name: echoserver spec: ingressClassName: alb @@ -120,7 +119,6 @@ metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing external-dns.alpha.kubernetes.io/hostname: echoserver.mycluster.example.org, echoserver.example.org - kubernetes.io/ingress.class: alb name: echoserver spec: ingressClassName: alb @@ -159,7 +157,6 @@ metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/ip-address-type: dualstack - kubernetes.io/ingress.class: alb name: echoserver spec: ingressClassName: alb diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index d5e7ad92b4..e749c16d7d 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -739,9 +739,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: "nginx" # use the one that corresponds to your ingress controller. spec: + ingressClassName: nginx rules: - host: server.example.com http: @@ -936,7 +935,8 @@ Running several fast polling ExternalDNS instances in a given account can easily * `--source=ingress --source=service` - specify multiple times for multiple sources * `--namespace=my-app` * `--label-filter=app in (my-app)` - * `--annotation-filter=kubernetes.io/ingress.class in (nginx-external)` - note that this filter would apply to services too.. + * `--ingress-class=nginx-external` + * `--annotation-filter=kubernetes.io/ingress.class in (nginx-external)` - note that this filter would apply to services too.. (deprecated in favor of `--ingress-class`) * Limit services watched by type (not applicable to ingress or other types) * `--service-type-filter=LoadBalancer` default `all` * Limit the hosted zones considered diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 640036e461..0e85d90267 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -416,9 +416,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: nginx spec: + ingressClassName: nginx rules: - host: server.example.com http: diff --git a/docs/tutorials/coredns.md b/docs/tutorials/coredns.md index f2c11b8c2f..5cd1223f29 100644 --- a/docs/tutorials/coredns.md +++ b/docs/tutorials/coredns.md @@ -198,9 +198,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: "nginx" spec: + ingressClassName: nginx rules: - host: nginx.example.org http: diff --git a/docs/tutorials/exoscale.md b/docs/tutorials/exoscale.md index d1e93cb0f0..047c1d6b8b 100644 --- a/docs/tutorials/exoscale.md +++ b/docs/tutorials/exoscale.md @@ -109,9 +109,9 @@ kind: Ingress metadata: name: nginx annotations: - kubernetes.io/ingress.class: nginx external-dns.alpha.kubernetes.io/target: {{ Elastic-IP-address }} spec: + ingressClassName: nginx rules: - host: via-ingress.example.com http: diff --git a/docs/tutorials/kube-ingress-aws.md b/docs/tutorials/kube-ingress-aws.md index bea5e56ac1..5cf37d4ec9 100644 --- a/docs/tutorials/kube-ingress-aws.md +++ b/docs/tutorials/kube-ingress-aws.md @@ -141,8 +141,6 @@ Create the following Ingress to expose the echoserver application to the Interne apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - annotations: - kubernetes.io/ingress.class: skipper name: echoserver spec: ingressClassName: skipper @@ -181,7 +179,6 @@ kind: Ingress metadata: annotations: external-dns.alpha.kubernetes.io/hostname: echoserver.mycluster.example.org, echoserver.example.org - kubernetes.io/ingress.class: skipper name: echoserver spec: ingressClassName: skipper @@ -218,7 +215,6 @@ kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/ip-address-type: dualstack - kubernetes.io/ingress.class: skipper name: echoserver spec: ingressClassName: skipper @@ -256,7 +252,6 @@ kind: Ingress metadata: annotations: zalando.org/aws-load-balancer-type: nlb - kubernetes.io/ingress.class: skipper name: echoserver spec: ingressClassName: skipper diff --git a/docs/tutorials/nginx-ingress.md b/docs/tutorials/nginx-ingress.md index f6c170b4c4..ce79f24d92 100644 --- a/docs/tutorials/nginx-ingress.md +++ b/docs/tutorials/nginx-ingress.md @@ -294,8 +294,6 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: nginx spec: ingressClassName: nginx rules: @@ -595,8 +593,6 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: nginx spec: ingressClassName: nginx rules: diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index 9ceb431953..66071e13d2 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -213,7 +213,7 @@ spec: Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. -In ExternalDNS containers args, make sure to specify `aws-zone-type` and either `ingress-class` or `annotation-filter` (depending on whether your cluster makes use of `ingressClassName`): +In ExternalDNS containers args, make sure to specify `aws-zone-type` and `ingress-class`: ```yaml apiVersion: apps/v1beta2 @@ -251,7 +251,7 @@ spec: Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. -In ExternalDNS containers args, make sure to specify `aws-zone-type` and either `ingress-class` or `annotation-filter` (depending on whether your cluster makes use of `ingressClassName`): +In ExternalDNS containers args, make sure to specify `aws-zone-type` and `ingress-class`: ```yaml apiVersion: apps/v1beta2 @@ -280,8 +280,6 @@ spec: - --registry=txt - --txt-owner-id=dev.k8s.nexus - --ingress-class=internal-ingress - # ... or, if you use annotations for ingress classes - # - --annotation-filter=kubernetes.io/ingress.class in (internal-ingress) - --aws-zone-type=private image: registry.k8s.io/external-dns/external-dns:v0.13.4 name: external-dns-private @@ -291,21 +289,17 @@ spec: For this setup to work, you need to create two Ingress definitions for your application. -At first, create a public Ingress definition (make sure to un-comment either the `annotations` or `ingressClassName` lines): +At first, create a public Ingress definition: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - # uncomment if you use annotations for ingress classes - # annotations: - # kubernetes.io/ingress.class: "external-ingress" labels: app: app name: app-public spec: - # uncomment if you use ingressClassName - # ingressClassName: external-ingress + ingressClassName: external-ingress rules: - host: app.domain.com http: @@ -318,21 +312,17 @@ spec: pathType: Prefix ``` -Then create a private Ingress definition (again, make sure to un-comment either the `annotations` or `ingressClassName` lines): +Then create a private Ingress definition: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - # uncomment if you use annotations for ingress classes - # annotations: - # kubernetes.io/ingress.class: "internal-ingress" labels: app: app name: app-private spec: - # uncomment if you use ingressClassName - # ingressClassName: internal-ingress + ingressClassName: internal-ingress rules: - host: app.domain.com http: diff --git a/docs/tutorials/rdns.md b/docs/tutorials/rdns.md index 684c7c64d5..529b1765c2 100644 --- a/docs/tutorials/rdns.md +++ b/docs/tutorials/rdns.md @@ -142,9 +142,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx - annotations: - kubernetes.io/ingress.class: "nginx" spec: + ingressClassName: nginx rules: - host: nginx.lb.rancher.cloud http: From 3288cc2f980064b2157028e068c76fb12ae37aee Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Date: Sat, 6 May 2023 14:40:36 +0100 Subject: [PATCH 059/154] feat(service): allow using target annotation --- docs/faq.md | 2 +- source/service.go | 50 +++++++++++---------- source/service_test.go | 99 +++++++++++++++++++++++++++++++++++++++++- source/source.go | 2 +- 4 files changed, 127 insertions(+), 26 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 044ee7aa86..a0104a0bfe 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -66,7 +66,7 @@ Regarding Ingress, we'll support: ### Are other Ingress Controllers supported? -For Ingress objects, ExternalDNS will attempt to discover the target hostname of the relevant Ingress Controller automatically. If you are using an Ingress Controller that is not listed above you may have issues with ExternalDNS not discovering Endpoints and consequently not creating any DNS records. As a workaround, it is possible to force create an Endpoint by manually specifying a target host/IP for the records to be created by setting the annotation `external-dns.alpha.kubernetes.io/target` in the Ingress object. +For Ingress objects, ExternalDNS will attempt to discover the target hostname of the relevant Ingress Controller automatically. If you are using an Ingress Controller that is not listed above you may have issues with ExternalDNS not discovering Endpoints and consequently not creating any DNS records. As a workaround, it is possible to force create an Endpoint by manually specifying a target host/IP for the records to be created by setting the annotation `external-dns.alpha.kubernetes.io/target` in the Ingress object. Note that services also support this annotation. Another reason you may want to override the ingress hostname or IP address is if you have an external mechanism for handling failover across ingress endpoints. Possible scenarios for this would include using [keepalived-vip](https://github.com/kubernetes/contrib/tree/HEAD/keepalived-vip) to manage failover faster than DNS TTLs might expire. diff --git a/source/service.go b/source/service.go index 925c327f24..e050660944 100644 --- a/source/service.go +++ b/source/service.go @@ -478,30 +478,34 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro var endpoints []*endpoint.Endpoint var targets endpoint.Targets - switch svc.Spec.Type { - case v1.ServiceTypeLoadBalancer: - if useClusterIP { - targets = append(targets, extractServiceIps(svc)...) - } else { - targets = append(targets, extractLoadBalancerTargets(svc, sc.resolveLoadBalancerHostname)...) - } - case v1.ServiceTypeClusterIP: - if sc.publishInternal { - targets = append(targets, extractServiceIps(svc)...) - } - if svc.Spec.ClusterIP == v1.ClusterIPNone { - endpoints = append(endpoints, sc.extractHeadlessEndpoints(svc, hostname, ttl)...) - } - case v1.ServiceTypeNodePort: - // add the nodeTargets and extract an SRV endpoint - targets, err = sc.extractNodePortTargets(svc) - if err != nil { - log.Errorf("Unable to extract targets from service %s/%s error: %v", svc.Namespace, svc.Name, err) - return endpoints + targets = getTargetsFromTargetAnnotation(svc.Annotations) + + if len(targets) == 0 { + switch svc.Spec.Type { + case v1.ServiceTypeLoadBalancer: + if useClusterIP { + targets = append(targets, extractServiceIps(svc)...) + } else { + targets = append(targets, extractLoadBalancerTargets(svc, sc.resolveLoadBalancerHostname)...) + } + case v1.ServiceTypeClusterIP: + if sc.publishInternal { + targets = append(targets, extractServiceIps(svc)...) + } + if svc.Spec.ClusterIP == v1.ClusterIPNone { + endpoints = append(endpoints, sc.extractHeadlessEndpoints(svc, hostname, ttl)...) + } + case v1.ServiceTypeNodePort: + // add the nodeTargets and extract an SRV endpoint + targets, err = sc.extractNodePortTargets(svc) + if err != nil { + log.Errorf("Unable to extract targets from service %s/%s error: %v", svc.Namespace, svc.Name, err) + return endpoints + } + endpoints = append(endpoints, sc.extractNodePortEndpoints(svc, targets, hostname, ttl)...) + case v1.ServiceTypeExternalName: + targets = append(targets, extractServiceExternalName(svc)...) } - endpoints = append(endpoints, sc.extractNodePortEndpoints(svc, targets, hostname, ttl)...) - case v1.ServiceTypeExternalName: - targets = append(targets, extractServiceExternalName(svc)...) } for _, t := range targets { diff --git a/source/service_test.go b/source/service_test.go index 98b400fca3..999f943eaa 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -1349,7 +1349,7 @@ func TestClusterIpServices(t *testing.T) { labelSelector string }{ { - title: "annotated ClusterIp services return an endpoint with Cluster IP", + title: "hostname annotated ClusterIp services return an endpoint with Cluster IP", svcNamespace: "testing", svcName: "foo", svcType: v1.ServiceTypeClusterIP, @@ -1361,6 +1361,48 @@ func TestClusterIpServices(t *testing.T) { {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}}, }, }, + { + title: "target annotated ClusterIp services return an endpoint with the specified A", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "4.3.2.1", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"4.3.2.1"}}, + }, + }, + { + title: "target annotated ClusterIp services return an endpoint with the specified CNAME", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org"}}, + }, + }, + { + title: "multiple target annotated ClusterIp services return an endpoint with the specified CNAMES", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.,baz.example.org.", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org", "baz.example.org"}}, + }, + }, { title: "hostname annotated ClusterIp services are ignored", svcNamespace: "testing", @@ -1373,6 +1415,33 @@ func TestClusterIpServices(t *testing.T) { clusterIP: "1.2.3.4", expected: []*endpoint.Endpoint{}, }, + { + title: "hostname and target annotated ClusterIp services are ignored", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + ignoreHostnameAnnotation: true, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{}, + }, + { + title: "hostname and target annotated ClusterIp services return an endpoint with the specified CNAME", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org"}}, + }, + }, { title: "non-annotated ClusterIp services with set fqdnTemplate return an endpoint with target IP", svcNamespace: "testing", @@ -1392,6 +1461,20 @@ func TestClusterIpServices(t *testing.T) { clusterIP: v1.ClusterIPNone, expected: []*endpoint.Endpoint{}, }, + { + title: "Headless services generate endpoints when target is specified", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.", + }, + clusterIP: v1.ClusterIPNone, + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org"}}, + }, + }, { title: "ClusterIP service with matching label generates an endpoint", svcNamespace: "testing", @@ -1405,6 +1488,20 @@ func TestClusterIpServices(t *testing.T) { }, labelSelector: "app=web-internal", }, + { + title: "ClusterIP service with matching label and target generates a CNAME endpoint", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + fqdnTemplate: "{{.Name}}.bar.example.com", + labels: map[string]string{"app": "web-internal"}, + annotations: map[string]string{targetAnnotationKey: "bar.example.com."}, + clusterIP: "4.5.6.7", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.bar.example.com", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.com"}}, + }, + labelSelector: "app=web-internal", + }, { title: "ClusterIP service without matching label generates an endpoint", svcNamespace: "testing", diff --git a/source/source.go b/source/source.go index 8573772c37..29169926c2 100644 --- a/source/source.go +++ b/source/source.go @@ -46,7 +46,7 @@ const ( accessAnnotationKey = "external-dns.alpha.kubernetes.io/access" // The annotation used for specifying the type of endpoints to use for headless services endpointsTypeAnnotationKey = "external-dns.alpha.kubernetes.io/endpoints-type" - // The annotation used for defining the desired ingress target + // The annotation used for defining the desired ingress/service target targetAnnotationKey = "external-dns.alpha.kubernetes.io/target" // The annotation used for defining the desired DNS record TTL ttlAnnotationKey = "external-dns.alpha.kubernetes.io/ttl" From 683663e9c21f0ed9a2cff073f555baec6752dadc Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Tue, 2 May 2023 22:55:08 -0700 Subject: [PATCH 060/154] IPv6 internal node IPs are usable externally --- docs/tutorials/nodes.md | 5 +- source/compatibility.go | 10 +-- source/node.go | 36 ++++++---- source/node_test.go | 57 +++++++++++++++- source/pod.go | 52 ++++++++------- source/pod_test.go | 142 +++++++++++++++++++++++++++++++++++++++- source/service.go | 21 ++++-- source/service_test.go | 37 +++++++++++ source/shared_test.go | 5 +- 9 files changed, 314 insertions(+), 51 deletions(-) diff --git a/docs/tutorials/nodes.md b/docs/tutorials/nodes.md index 46f21da5d8..b99a2f9ca3 100644 --- a/docs/tutorials/nodes.md +++ b/docs/tutorials/nodes.md @@ -3,8 +3,9 @@ This tutorial describes how to configure ExternalDNS to use the cluster nodes as source. Using nodes (`--source=node`) as source is possible to synchronize a DNS zone with the nodes of a cluster. -The node source adds an `A` record per each node `externalIP` (if not found, node's `internalIP` is used). -The TTL record can be set with the `external-dns.alpha.kubernetes.io/ttl` node annotation. +The node source adds an `A` record per each node `externalIP` (if not found, any IPv4 `internalIP` is used instead). +It also adds an `AAAA` record per each node IPv6 `internalIP`. +The TTL of the records can be set with the `external-dns.alpha.kubernetes.io/ttl` node annotation. ## Manifest (for cluster without RBAC enabled) diff --git a/source/compatibility.go b/source/compatibility.go index bc6e19abf9..1953b76ca9 100644 --- a/source/compatibility.go +++ b/source/compatibility.go @@ -157,11 +157,13 @@ func legacyEndpointsFromDNSControllerNodePortService(svc *v1.Service, sc *servic continue } for _, address := range node.Status.Addresses { - if address.Type == v1.NodeExternalIP && isExternal { - endpoints = append(endpoints, endpoint.NewEndpoint(hostname, endpoint.RecordTypeA, address.Address)) + recordType := suitableType(address.Address) + // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. + if isExternal && (address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA)) { + endpoints = append(endpoints, endpoint.NewEndpoint(hostname, recordType, address.Address)) } - if address.Type == v1.NodeInternalIP && isInternal { - endpoints = append(endpoints, endpoint.NewEndpoint(hostname, endpoint.RecordTypeA, address.Address)) + if isInternal && address.Type == v1.NodeInternalIP { + endpoints = append(endpoints, endpoint.NewEndpoint(hostname, recordType, address.Address)) } } } diff --git a/source/node.go b/source/node.go index b0e672d732..39135ceaf1 100644 --- a/source/node.go +++ b/source/node.go @@ -76,6 +76,11 @@ func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotat }, nil } +type endpointsKey struct { + dnsName string + recordType string +} + // Endpoints returns endpoint objects for each service that should be processed. func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { nodes, err := ns.nodeInformer.Lister().List(labels.Everything()) @@ -88,7 +93,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro return nil, err } - endpoints := map[string]*endpoint.Endpoint{} + endpoints := map[endpointsKey]*endpoint.Endpoint{} // create endpoints for all nodes for _, node := range nodes { @@ -109,8 +114,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro // create new endpoint with the information we already have ep := &endpoint.Endpoint{ - RecordType: "A", // hardcoded DNS record type - RecordTTL: ttl, + RecordTTL: ttl, } if ns.fqdnTemplate != nil { @@ -134,14 +138,19 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro return nil, fmt.Errorf("failed to get node address from %s: %s", node.Name, err.Error()) } - ep.Targets = endpoint.Targets(addrs) ep.Labels = endpoint.NewLabels() - - log.Debugf("adding endpoint %s", ep) - if _, ok := endpoints[ep.DNSName]; ok { - endpoints[ep.DNSName].Targets = append(endpoints[ep.DNSName].Targets, ep.Targets...) - } else { - endpoints[ep.DNSName] = ep + for _, addr := range addrs { + log.Debugf("adding endpoint %s target %s", ep, addr) + key := endpointsKey{ + dnsName: ep.DNSName, + recordType: suitableType(addr), + } + if _, ok := endpoints[key]; !ok { + epCopy := *ep + epCopy.RecordType = key.recordType + endpoints[key] = &epCopy + } + endpoints[key].Targets = append(endpoints[key].Targets, addr) } } @@ -163,13 +172,18 @@ func (ns *nodeSource) nodeAddresses(node *v1.Node) ([]string, error) { v1.NodeExternalIP: {}, v1.NodeInternalIP: {}, } + var ipv6Addresses []string for _, addr := range node.Status.Addresses { addresses[addr.Type] = append(addresses[addr.Type], addr.Address) + // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. + if addr.Type == v1.NodeInternalIP && suitableType(addr.Address) == endpoint.RecordTypeAAAA { + ipv6Addresses = append(ipv6Addresses, addr.Address) + } } if len(addresses[v1.NodeExternalIP]) > 0 { - return addresses[v1.NodeExternalIP], nil + return append(addresses[v1.NodeExternalIP], ipv6Addresses...), nil } if len(addresses[v1.NodeInternalIP]) > 0 { diff --git a/source/node_test.go b/source/node_test.go index 901c1baa11..885d9f54e1 100644 --- a/source/node_test.go +++ b/source/node_test.go @@ -127,6 +127,19 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, + { + "ipv6 node with fqdn returns one endpoint", + "", + "", + "node1.example.org", + []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2001:DB8::8"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}}, + }, + false, + }, { "node with fqdn template returns endpoint with expanded hostname", "", @@ -166,6 +179,20 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, + { + "node with fqdn template returns two endpoints with dual-stack IP addresses and expanded hostname", + "", + "{{.Name}}.example.org", + "node1", + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}}, + {RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}}, + }, + false, + }, { "node with both external and internal IP returns an endpoint with external IP", "", @@ -179,6 +206,20 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, + { + "node with both external, internal, and IPv6 IP returns endpoints with external IPs", + "", + "", + "node1", + []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}}, + {RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}}, + }, + false, + }, { "node with only internal IP returns an endpoint with internal IP", "", @@ -192,6 +233,20 @@ func testNodeSourceEndpoints(t *testing.T) { }, false, }, + { + "node with only internal IPs returns endpoints with internal IPs", + "", + "", + "node1", + []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}}, + map[string]string{}, + map[string]string{}, + []*endpoint.Endpoint{ + {RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}}, + {RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}}, + }, + false, + }, { "node with neither external nor internal IP returns no endpoints", "", @@ -318,7 +373,7 @@ func testNodeSourceEndpoints(t *testing.T) { false, }, { - "node with nil Lables returns valid endpoint", + "node with nil Labels returns valid endpoint", "", "", "node1", diff --git a/source/pod.go b/source/pod.go index 36e6ffe50e..87772d75bb 100644 --- a/source/pod.go +++ b/source/pod.go @@ -76,13 +76,18 @@ func NewPodSource(ctx context.Context, kubeClient kubernetes.Interface, namespac func (*podSource) AddEventHandler(ctx context.Context, handler func()) { } +type endpointKey struct { + domain string + recordType string +} + func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { pods, err := ps.podInformer.Lister().Pods(ps.namespace).List(labels.Everything()) if err != nil { return nil, err } - domains := make(map[string][]string) + endpointMap := make(map[endpointKey][]string) for _, pod := range pods { if !pod.Spec.HostNetwork { log.Debugf("skipping pod %s. hostNetwork=false", pod.Name) @@ -90,50 +95,51 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error } if domain, ok := pod.Annotations[internalHostnameAnnotationKey]; ok { - if _, ok := domains[domain]; !ok { - domains[domain] = []string{} - } - domains[domain] = append(domains[domain], pod.Status.PodIP) + addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) } if domain, ok := pod.Annotations[hostnameAnnotationKey]; ok { - if _, ok := domains[domain]; !ok { - domains[domain] = []string{} - } - node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName) for _, address := range node.Status.Addresses { - if address.Type == corev1.NodeExternalIP { - domains[domain] = append(domains[domain], address.Address) + recordType := suitableType(address.Address) + // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. + if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) { + addToEndpointMap(endpointMap, domain, recordType, address.Address) } } } if ps.compatibility == "kops-dns-controller" { if domain, ok := pod.Annotations[kopsDNSControllerInternalHostnameAnnotationKey]; ok { - if _, ok := domains[domain]; !ok { - domains[domain] = []string{} - } - domains[domain] = append(domains[domain], pod.Status.PodIP) + addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) } if domain, ok := pod.Annotations[kopsDNSControllerHostnameAnnotationKey]; ok { - if _, ok := domains[domain]; !ok { - domains[domain] = []string{} - } - node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName) for _, address := range node.Status.Addresses { - if address.Type == corev1.NodeExternalIP { - domains[domain] = append(domains[domain], address.Address) + recordType := suitableType(address.Address) + // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. + if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) { + addToEndpointMap(endpointMap, domain, recordType, address.Address) } } } } } endpoints := []*endpoint.Endpoint{} - for domain, targets := range domains { - endpoints = append(endpoints, endpoint.NewEndpoint(domain, endpoint.RecordTypeA, targets...)) + for key, targets := range endpointMap { + endpoints = append(endpoints, endpoint.NewEndpoint(key.domain, key.recordType, targets...)) } return endpoints, nil } + +func addToEndpointMap(endpointMap map[endpointKey][]string, domain string, recordType string, address string) { + key := endpointKey{ + domain: domain, + recordType: recordType, + } + if _, ok := endpointMap[key]; !ok { + endpointMap[key] = []string{} + } + endpointMap[key] = append(endpointMap[key], address) +} diff --git a/source/pod_test.go b/source/pod_test.go index c138aaf5fd..5a57aedc26 100644 --- a/source/pod_test.go +++ b/source/pod_test.go @@ -41,7 +41,7 @@ func TestPodSource(t *testing.T) { pods []*corev1.Pod }{ { - "create records based on pod's external and internal IPs", + "create IPv4 records based on pod's external and internal IPs", "", "", []*endpoint.Endpoint{ @@ -111,7 +111,7 @@ func TestPodSource(t *testing.T) { }, }, { - "create records based on pod's external and internal IPs using DNS Controller annotations", + "create IPv4 records based on pod's external and internal IPs using DNS Controller annotations", "", "kops-dns-controller", []*endpoint.Endpoint{ @@ -180,12 +180,149 @@ func TestPodSource(t *testing.T) { }, }, }, + { + "create IPv6 records based on pod's external and internal IPs", + "", + "", + []*endpoint.Endpoint{ + {DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, + {DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, + }, + false, + []*corev1.Node{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node1", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + {Type: corev1.NodeInternalIP, Address: "2001:DB8::1"}, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node2", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + {Type: corev1.NodeInternalIP, Address: "2001:DB8::2"}, + }, + }, + }, + }, + []*corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod1", + Namespace: "kube-system", + Annotations: map[string]string{ + internalHostnameAnnotationKey: "internal.a.foo.example.org", + hostnameAnnotationKey: "a.foo.example.org", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + NodeName: "my-node1", + }, + Status: corev1.PodStatus{ + PodIP: "2001:DB8::1", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod2", + Namespace: "kube-system", + Annotations: map[string]string{ + internalHostnameAnnotationKey: "internal.a.foo.example.org", + hostnameAnnotationKey: "a.foo.example.org", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + NodeName: "my-node2", + }, + Status: corev1.PodStatus{ + PodIP: "2001:DB8::2", + }, + }, + }, + }, + { + "create IPv6 records based on pod's external and internal IPs using DNS Controller annotations", + "", + "kops-dns-controller", + []*endpoint.Endpoint{ + {DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, + {DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, + }, + false, + []*corev1.Node{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node1", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + {Type: corev1.NodeInternalIP, Address: "2001:DB8::1"}, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node2", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + {Type: corev1.NodeInternalIP, Address: "2001:DB8::2"}, + }, + }, + }, + }, + []*corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod1", + Namespace: "kube-system", + Annotations: map[string]string{ + kopsDNSControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org", + kopsDNSControllerHostnameAnnotationKey: "a.foo.example.org", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + NodeName: "my-node1", + }, + Status: corev1.PodStatus{ + PodIP: "2001:DB8::1", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod2", + Namespace: "kube-system", + Annotations: map[string]string{ + kopsDNSControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org", + kopsDNSControllerHostnameAnnotationKey: "a.foo.example.org", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + NodeName: "my-node2", + }, + Status: corev1.PodStatus{ + PodIP: "2001:DB8::2", + }, + }, + }, + }, { "create multiple records", "", "", []*endpoint.Endpoint{ {DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1"}, RecordType: endpoint.RecordTypeAAAA}, {DNSName: "b.foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA}, }, false, @@ -197,6 +334,7 @@ func TestPodSource(t *testing.T) { Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ {Type: corev1.NodeExternalIP, Address: "54.10.11.1"}, + {Type: corev1.NodeInternalIP, Address: "2001:DB8::1"}, {Type: corev1.NodeInternalIP, Address: "10.0.1.1"}, }, }, diff --git a/source/service.go b/source/service.go index 925c327f24..58270cdcc3 100644 --- a/source/service.go +++ b/source/service.go @@ -216,7 +216,10 @@ func (sc *serviceSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e }) // Use stable sort to not disrupt the order of services sort.SliceStable(endpoints, func(i, j int) bool { - return endpoints[i].DNSName < endpoints[j].DNSName + if endpoints[i].DNSName != endpoints[j].DNSName { + return endpoints[i].DNSName < endpoints[j].DNSName + } + return endpoints[i].RecordType < endpoints[j].RecordType }) mergedEndpoints := []*endpoint.Endpoint{} mergedEndpoints = append(mergedEndpoints, endpoints[0]) @@ -308,8 +311,8 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri return endpoints } for _, address := range node.Status.Addresses { - if address.Type == v1.NodeExternalIP { - targets = endpoint.Targets{address.Address} + if address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && suitableType(address.Address) == endpoint.RecordTypeAAAA) { + targets = append(targets, address.Address) log.Debugf("Generating matching endpoint %s with NodeExternalIP %s", headlessDomain, address.Address) } } @@ -499,7 +502,7 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro log.Errorf("Unable to extract targets from service %s/%s error: %v", svc.Namespace, svc.Name, err) return endpoints } - endpoints = append(endpoints, sc.extractNodePortEndpoints(svc, targets, hostname, ttl)...) + endpoints = append(endpoints, sc.extractNodePortEndpoints(svc, hostname, ttl)...) case v1.ServiceTypeExternalName: targets = append(targets, extractServiceExternalName(svc)...) } @@ -587,6 +590,7 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe var ( internalIPs endpoint.Targets externalIPs endpoint.Targets + ipv6IPs endpoint.Targets nodes []*v1.Node err error ) @@ -634,24 +638,27 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe externalIPs = append(externalIPs, address.Address) case v1.NodeInternalIP: internalIPs = append(internalIPs, address.Address) + if suitableType(address.Address) == endpoint.RecordTypeAAAA { + ipv6IPs = append(ipv6IPs, address.Address) + } } } } access := getAccessFromAnnotations(svc.Annotations) if access == "public" { - return externalIPs, nil + return append(externalIPs, ipv6IPs...), nil } if access == "private" { return internalIPs, nil } if len(externalIPs) > 0 { - return externalIPs, nil + return append(externalIPs, ipv6IPs...), nil } return internalIPs, nil } -func (sc *serviceSource) extractNodePortEndpoints(svc *v1.Service, nodeTargets endpoint.Targets, hostname string, ttl endpoint.TTL) []*endpoint.Endpoint { +func (sc *serviceSource) extractNodePortEndpoints(svc *v1.Service, hostname string, ttl endpoint.TTL) []*endpoint.Endpoint { var endpoints []*endpoint.Endpoint for _, port := range svc.Spec.Ports { diff --git a/source/service_test.go b/source/service_test.go index 98b400fca3..45737adb7c 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -1518,6 +1518,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1527,6 +1528,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1537,6 +1539,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1559,6 +1562,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1569,6 +1573,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1584,6 +1589,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.bar.example.com", Targets: endpoint.Targets{"0 50 30192 foo.bar.example.com"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1593,6 +1599,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1603,6 +1610,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1619,6 +1627,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1627,6 +1636,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Status: v1.NodeStatus{ Addresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1636,6 +1646,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Status: v1.NodeStatus{ Addresses: []v1.NodeAddress{ {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1652,6 +1663,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1661,6 +1673,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1671,6 +1684,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1691,6 +1705,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1700,6 +1715,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1710,6 +1726,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1731,6 +1748,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1740,6 +1758,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1750,6 +1769,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1768,6 +1788,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { expected: []*endpoint.Endpoint{ {DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org"}, RecordType: endpoint.RecordTypeSRV}, {DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1777,6 +1798,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1787,6 +1809,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1804,7 +1827,9 @@ func TestServiceSourceNodePortServices(t *testing.T) { }, expected: []*endpoint.Endpoint{ {DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1"}}, + {DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1"}}, {DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1"}}, + {DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1"}}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1817,6 +1842,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1830,6 +1856,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1846,7 +1873,9 @@ func TestServiceSourceNodePortServices(t *testing.T) { }, expected: []*endpoint.Endpoint{ {DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}}, + {DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}}, {DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}}, + {DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1859,6 +1888,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1872,6 +1902,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1888,7 +1919,9 @@ func TestServiceSourceNodePortServices(t *testing.T) { }, expected: []*endpoint.Endpoint{ {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}}, + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}}, {DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}}, + {DNSName: "bar.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}}, }, nodes: []*v1.Node{{ ObjectMeta: metav1.ObjectMeta{ @@ -1901,6 +1934,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1914,6 +1948,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, @@ -1942,6 +1977,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.1"}, {Type: v1.NodeInternalIP, Address: "10.0.1.1"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::1"}, }, }, }, { @@ -1955,6 +1991,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { Addresses: []v1.NodeAddress{ {Type: v1.NodeExternalIP, Address: "54.10.11.2"}, {Type: v1.NodeInternalIP, Address: "10.0.1.2"}, + {Type: v1.NodeInternalIP, Address: "2001:DB8::2"}, }, }, }}, diff --git a/source/shared_test.go b/source/shared_test.go index 9cdc58d22a..11828dbe2e 100644 --- a/source/shared_test.go +++ b/source/shared_test.go @@ -29,11 +29,14 @@ func sortEndpoints(endpoints []*endpoint.Endpoint) { sort.Strings([]string(ep.Targets)) } sort.Slice(endpoints, func(i, k int) bool { - // Sort by DNSName and Targets + // Sort by DNSName, RecordType, and Targets ei, ek := endpoints[i], endpoints[k] if ei.DNSName != ek.DNSName { return ei.DNSName < ek.DNSName } + if ei.RecordType != ek.RecordType { + return ei.RecordType < ek.RecordType + } // Targets are sorted ahead of time. for j, ti := range ei.Targets { if j >= len(ek.Targets) { From ea4eb4230c7de239245a2f70de8a1446409df463 Mon Sep 17 00:00:00 2001 From: David Mealo Date: Mon, 8 May 2023 10:03:21 -0400 Subject: [PATCH 061/154] Update azure.md --- docs/tutorials/azure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/azure.md b/docs/tutorials/azure.md index b6d8850340..083034f58b 100644 --- a/docs/tutorials/azure.md +++ b/docs/tutorials/azure.md @@ -50,7 +50,7 @@ The following fields are used: * `tenantId` (**required**) - run `az account show --query "tenantId"` or by selecting Azure Active Directory in the Azure Portal and checking the _Directory ID_ under Properties. * `subscriptionId` (**required**) - run `az account show --query "id"` or by selecting Subscriptions in the Azure Portal. * `resourceGroup` (**required**) is the Resource Group created in a previous step that contains the Azure DNS Zone. -* `aadClientID` and `aaClientSecret` are associated with the Service Principal. This is only used with Service Principal method documented in the next section. +* `aadClientID` and `aadClientSecret` are associated with the Service Principal. This is only used with Service Principal method documented in the next section. * `useManagedIdentityExtension` - this is set to `true` if you use either AKS Kubelet Identity or AAD Pod Identities methods documented in the next section. * `userAssignedIdentityID` - this contains the client id from the Managed identitty when using the AAD Pod Identities method documented in the next setion. From 7feb8d67e9173eee9f5114de31007a42a85f1e04 Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Tue, 9 May 2023 08:45:14 +0200 Subject: [PATCH 062/154] docs: remove product mention. --- docs/faq.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index adefacb813..43731a3712 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -260,11 +260,11 @@ Sometimes you need to run an internal and an external dns service. The internal one should provision hostnames used on the internal network (perhaps inside a VPC), and the external one to expose DNS to the internet. To do this with ExternalDNS you can use the `--ingress-class` flag to specifically tie an instance of ExternalDNS to an instance of a ingress controller. -Let's assume you have two ingress controllers, `nginx-internal` and `nginx-external`. -You can then start two ExternalDNS providers, one with `--ingress-class=nginx-internal` and one with `--ingress-class=nginx-external`. +Let's assume you have two ingress controllers, `internal` and `external`. +You can then start two ExternalDNS providers, one with `--ingress-class=internal` and one with `--ingress-class=external`. If you need to search for multiple ingress classes, you can specify the flag multiple times, like so: -`--ingress-class=nginx-internal --ingress-class=alb-ingress-internal`. +`--ingress-class=internal --ingress-class=external`. The `--ingress-class` flag will check both the `spec.ingressClassName` field and the deprecated `kubernetes.io/ingress.class` annotation. The `spec.ingressClassName` tasks precedence over the annotation if both are supplied. From 7b940026bef96a78d37a841671cf2b6f69550145 Mon Sep 17 00:00:00 2001 From: Arnaud Lefray Date: Tue, 9 May 2023 08:46:56 +0200 Subject: [PATCH 063/154] docs(aws): remove mention of deprecated annotation filter --- docs/tutorials/aws.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index e749c16d7d..f77f8017f2 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -936,7 +936,6 @@ Running several fast polling ExternalDNS instances in a given account can easily * `--namespace=my-app` * `--label-filter=app in (my-app)` * `--ingress-class=nginx-external` - * `--annotation-filter=kubernetes.io/ingress.class in (nginx-external)` - note that this filter would apply to services too.. (deprecated in favor of `--ingress-class`) * Limit services watched by type (not applicable to ingress or other types) * `--service-type-filter=LoadBalancer` default `all` * Limit the hosted zones considered From 4745ddbb0eca0fc9d1571bb77c7aec148d662c99 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Tue, 9 May 2023 19:42:56 -0700 Subject: [PATCH 064/154] Address review comment --- source/node.go | 9 ++------- source/pod.go | 9 ++------- source/source.go | 6 ++++++ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/source/node.go b/source/node.go index 39135ceaf1..5e287e9a00 100644 --- a/source/node.go +++ b/source/node.go @@ -76,11 +76,6 @@ func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotat }, nil } -type endpointsKey struct { - dnsName string - recordType string -} - // Endpoints returns endpoint objects for each service that should be processed. func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { nodes, err := ns.nodeInformer.Lister().List(labels.Everything()) @@ -93,7 +88,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro return nil, err } - endpoints := map[endpointsKey]*endpoint.Endpoint{} + endpoints := map[endpointKey]*endpoint.Endpoint{} // create endpoints for all nodes for _, node := range nodes { @@ -141,7 +136,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro ep.Labels = endpoint.NewLabels() for _, addr := range addrs { log.Debugf("adding endpoint %s target %s", ep, addr) - key := endpointsKey{ + key := endpointKey{ dnsName: ep.DNSName, recordType: suitableType(addr), } diff --git a/source/pod.go b/source/pod.go index 87772d75bb..123468539f 100644 --- a/source/pod.go +++ b/source/pod.go @@ -76,11 +76,6 @@ func NewPodSource(ctx context.Context, kubeClient kubernetes.Interface, namespac func (*podSource) AddEventHandler(ctx context.Context, handler func()) { } -type endpointKey struct { - domain string - recordType string -} - func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { pods, err := ps.podInformer.Lister().Pods(ps.namespace).List(labels.Everything()) if err != nil { @@ -128,14 +123,14 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error } endpoints := []*endpoint.Endpoint{} for key, targets := range endpointMap { - endpoints = append(endpoints, endpoint.NewEndpoint(key.domain, key.recordType, targets...)) + endpoints = append(endpoints, endpoint.NewEndpoint(key.dnsName, key.recordType, targets...)) } return endpoints, nil } func addToEndpointMap(endpointMap map[endpointKey][]string, domain string, recordType string, address string) { key := endpointKey{ - domain: domain, + dnsName: domain, recordType: recordType, } if _, ok := endpointMap[key]; !ok { diff --git a/source/source.go b/source/source.go index 8573772c37..91b83bb4fc 100644 --- a/source/source.go +++ b/source/source.go @@ -86,6 +86,12 @@ type Source interface { AddEventHandler(context.Context, func()) } +// endpointKey is the type of a map key for separating endpoints or targets. +type endpointKey struct { + dnsName string + recordType string +} + func getTTLFromAnnotations(annotations map[string]string) (endpoint.TTL, error) { ttlNotConfigured := endpoint.TTL(0) ttlAnnotation, exists := annotations[ttlAnnotationKey] From e03df8b50497a6977dd360dd49878a5c981bb9bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 04:00:34 +0000 Subject: [PATCH 065/154] build(deps): bump alpine from 3.17 to 3.18 Bumps alpine from 3.17 to 3.18. --- updated-dependencies: - dependency-name: alpine dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 55b72749d3..8590ad6332 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ RUN go mod download COPY . . -FROM alpine:3.17 +FROM alpine:3.18 RUN apk update && apk add "libcrypto3>=3.0.8-r1" "libssl3>=3.0.8-r1" && rm -rf /var/cache/apt/* From 41c705e471c8447a12965c8eea2d5e55bf270513 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sat, 6 May 2023 16:46:01 -0700 Subject: [PATCH 066/154] Support AAAA records from headless services --- source/service.go | 31 ++-- source/service_test.go | 373 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 385 insertions(+), 19 deletions(-) diff --git a/source/service.go b/source/service.go index 58270cdcc3..7eac4c5118 100644 --- a/source/service.go +++ b/source/service.go @@ -271,7 +271,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri endpointsType := getEndpointsTypeFromAnnotations(svc.Annotations) - targetsByHeadlessDomain := make(map[string]endpoint.Targets) + targetsByHeadlessDomainAndType := make(map[endpointKey]endpoint.Targets) for _, subset := range endpointsObject.Subsets { addresses := subset.Addresses if svc.Spec.PublishNotReadyAddresses || sc.alwaysPublishNotReadyAddresses { @@ -324,18 +324,29 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri log.Debugf("Generating matching endpoint %s with EndpointAddress IP %s", headlessDomain, address.IP) } } - targetsByHeadlessDomain[headlessDomain] = append(targetsByHeadlessDomain[headlessDomain], targets...) + for _, target := range targets { + key := endpointKey{ + dnsName: headlessDomain, + recordType: suitableType(target), + } + targetsByHeadlessDomainAndType[key] = append(targetsByHeadlessDomainAndType[key], target) + } } } } - headlessDomains := []string{} - for headlessDomain := range targetsByHeadlessDomain { - headlessDomains = append(headlessDomains, headlessDomain) + headlessKeys := []endpointKey{} + for headlessKey := range targetsByHeadlessDomainAndType { + headlessKeys = append(headlessKeys, headlessKey) } - sort.Strings(headlessDomains) - for _, headlessDomain := range headlessDomains { - allTargets := targetsByHeadlessDomain[headlessDomain] + sort.Slice(headlessKeys, func(i, j int) bool { + if headlessKeys[i].dnsName != headlessKeys[j].dnsName { + return headlessKeys[i].dnsName < headlessKeys[j].dnsName + } + return headlessKeys[i].recordType < headlessKeys[j].recordType + }) + for _, headlessKey := range headlessKeys { + allTargets := targetsByHeadlessDomainAndType[headlessKey] targets := []string{} deduppedTargets := map[string]struct{}{} @@ -350,9 +361,9 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri } if ttl.IsConfigured() { - endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessDomain, endpoint.RecordTypeA, ttl, targets...)) + endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessKey.dnsName, headlessKey.recordType, ttl, targets...)) } else { - endpoints = append(endpoints, endpoint.NewEndpoint(headlessDomain, endpoint.RecordTypeA, targets...)) + endpoints = append(endpoints, endpoint.NewEndpoint(headlessKey.dnsName, headlessKey.recordType, targets...)) } } diff --git a/source/service_test.go b/source/service_test.go index 45737adb7c..66ef2a830f 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -2118,7 +2118,7 @@ func TestHeadlessServices(t *testing.T) { expectError bool }{ { - "annotated Headless services return endpoints for each selected Pod", + "annotated Headless services return IPv4 endpoints for each selected Pod", "", "testing", "foo", @@ -2150,6 +2150,39 @@ func TestHeadlessServices(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 endpoints for each selected Pod", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::2"}, + []string{"", ""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1"}, + []string{"foo-0", "foo-1"}, + []bool{true, true}, + false, + []v1.Node{}, + []*endpoint.Endpoint{ + {DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1"}}, + {DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::2"}}, + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}}, + }, + false, + }, { "hostname annotated Headless services are ignored", "", @@ -2180,7 +2213,7 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return endpoints with TTL for each selected Pod", + "annotated Headless services return IPv4 endpoints with TTL for each selected Pod", "", "testing", "foo", @@ -2213,6 +2246,40 @@ func TestHeadlessServices(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 endpoints with TTL for each selected Pod", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + ttlAnnotationKey: "1", + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::2"}, + []string{"", ""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1"}, + []string{"foo-0", "foo-1"}, + []bool{true, true}, + false, + []v1.Node{}, + []*endpoint.Endpoint{ + {DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1"}, RecordTTL: endpoint.TTL(1)}, + {DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::2"}, RecordTTL: endpoint.TTL(1)}, + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}, RecordTTL: endpoint.TTL(1)}, + }, + false, + }, { "annotated Headless services return endpoints for each selected Pod, which are in running state", "", @@ -2310,7 +2377,7 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return only a unique set of targets", + "annotated Headless services return only a unique set of IPv4 targets", "", "testing", "foo", @@ -2341,7 +2408,38 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return targets from pod annotation", + "annotated Headless services return only a unique set of IPv6 targets", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::1", "2001:db8::2"}, + []string{"", "", ""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1", "foo-3"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{}, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}}, + }, + false, + }, + { + "annotated Headless services return IPv4 targets from pod annotation", "", "testing", "foo", @@ -2374,7 +2472,40 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return targets from node external IP if endpoints-type annotation is set", + "annotated Headless services return IPv6 targets from pod annotation", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + map[string]string{ + targetAnnotationKey: "2001:db8::4", + }, + v1.ClusterIPNone, + []string{"2001:db8::1"}, + []string{""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{}, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}}, + }, + false, + }, + { + "annotated Headless services return IPv4 targets from node external IP if endpoints-type annotation is set", "", "testing", "foo", @@ -2417,7 +2548,98 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return targets from hostIP if endpoints-type annotation is set", + "annotated Headless services return IPv6 targets from node external IP if endpoints-type annotation is set", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP, + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1"}, + []string{""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{ + { + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: "2001:db8::4", + }, + }, + }, + }, + }, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}}, + }, + false, + }, + { + "annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP, + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"1.1.1.1"}, + []string{""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{ + { + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{ + { + Type: v1.NodeExternalIP, + Address: "1.2.3.4", + }, + { + Type: v1.NodeInternalIP, + Address: "2001:db8::4", + }, + }, + }, + }, + }, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}}, + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}}, + }, + false, + }, + { + "annotated Headless services return IPv4 targets from hostIP if endpoints-type annotation is set", "", "testing", "foo", @@ -2448,6 +2670,38 @@ func TestHeadlessServices(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 targets from hostIP if endpoints-type annotation is set", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + endpointsTypeAnnotationKey: EndpointsTypeHostIP, + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1"}, + []string{"2001:db8::4"}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{}, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}}, + }, + false, + }, } { tc := tc t.Run(tc.title, func(t *testing.T) { @@ -2590,7 +2844,7 @@ func TestHeadlessServicesHostIP(t *testing.T) { expectError bool }{ { - "annotated Headless services return endpoints for each selected Pod", + "annotated Headless services return IPv4 endpoints for each selected Pod", "", "testing", "foo", @@ -2623,6 +2877,40 @@ func TestHeadlessServicesHostIP(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 endpoints for each selected Pod", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::2"}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1"}, + []string{"foo-0", "foo-1"}, + []bool{true, true}, + []*v1.ObjectReference{ + {APIVersion: "", Kind: "Pod", Name: "foo-0"}, + {APIVersion: "", Kind: "Pod", Name: "foo-1"}, + }, + false, + []*endpoint.Endpoint{ + {DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1"}}, + {DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::2"}}, + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}}, + }, + false, + }, { "hostname annotated Headless services are ignored", "", @@ -2654,7 +2942,7 @@ func TestHeadlessServicesHostIP(t *testing.T) { false, }, { - "annotated Headless services return endpoints with TTL for each selected Pod", + "annotated Headless services return IPv4 endpoints with TTL for each selected Pod", "", "testing", "foo", @@ -2688,6 +2976,41 @@ func TestHeadlessServicesHostIP(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 endpoints with TTL for each selected Pod", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + ttlAnnotationKey: "1", + }, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::2"}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1"}, + []string{"foo-0", "foo-1"}, + []bool{true, true}, + []*v1.ObjectReference{ + {APIVersion: "", Kind: "Pod", Name: "foo-0"}, + {APIVersion: "", Kind: "Pod", Name: "foo-1"}, + }, + false, + []*endpoint.Endpoint{ + {DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1"}, RecordTTL: endpoint.TTL(1)}, + {DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::2"}, RecordTTL: endpoint.TTL(1)}, + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}, RecordTTL: endpoint.TTL(1)}, + }, + false, + }, { "annotated Headless services return endpoints for each selected Pod, which are in running state", "", @@ -2756,7 +3079,7 @@ func TestHeadlessServicesHostIP(t *testing.T) { false, }, { - "annotated Headless services return endpoints for pods missing hostname", + "annotated Headless services return IPv4 endpoints for pods missing hostname", "", "testing", "foo", @@ -2787,6 +3110,38 @@ func TestHeadlessServicesHostIP(t *testing.T) { }, false, }, + { + "annotated Headless services return IPv6 endpoints for pods missing hostname", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + v1.ClusterIPNone, + []string{"2001:db8::1", "2001:db8::2"}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo-0", "foo-1"}, + []string{"", ""}, + []bool{true, true}, + []*v1.ObjectReference{ + {APIVersion: "", Kind: "Pod", Name: "foo-0"}, + {APIVersion: "", Kind: "Pod", Name: "foo-1"}, + }, + false, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1", "2001:db8::2"}}, + }, + false, + }, { "annotated Headless services without a targetRef has no endpoints", "", From 47a0f74f61c85a6899487558d3c04c26b23c875b Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sat, 6 May 2023 16:59:39 -0700 Subject: [PATCH 067/154] Add test for IPv6 ExternalName service --- source/service_test.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/source/service_test.go b/source/service_test.go index 66ef2a830f..7f3255dd5f 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -3295,7 +3295,7 @@ func TestExternalServices(t *testing.T) { expectError bool }{ { - "external services return an A endpoint for the external name that is an IP address", + "external services return an A endpoint for the external name that is an IPv4 address", "", "testing", "foo", @@ -3313,6 +3313,25 @@ func TestExternalServices(t *testing.T) { }, false, }, + { + "external services return an AAAA endpoint for the external name that is an IPv6 address", + "", + "testing", + "foo", + v1.ServiceTypeExternalName, + "", + "", + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + }, + "2001:db8::111", + []*endpoint.Endpoint{ + {DNSName: "service.example.org", Targets: endpoint.Targets{"2001:db8::111"}, RecordType: endpoint.RecordTypeAAAA}, + }, + false, + }, { "external services return a CNAME endpoint for the external name that is a domain", "", From 140444749b7e9a3e43b1acbf00f4b2b4b25c2c9a Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Date: Thu, 11 May 2023 11:44:36 +0100 Subject: [PATCH 068/154] remove comment from ingress --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index a0104a0bfe..044ee7aa86 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -66,7 +66,7 @@ Regarding Ingress, we'll support: ### Are other Ingress Controllers supported? -For Ingress objects, ExternalDNS will attempt to discover the target hostname of the relevant Ingress Controller automatically. If you are using an Ingress Controller that is not listed above you may have issues with ExternalDNS not discovering Endpoints and consequently not creating any DNS records. As a workaround, it is possible to force create an Endpoint by manually specifying a target host/IP for the records to be created by setting the annotation `external-dns.alpha.kubernetes.io/target` in the Ingress object. Note that services also support this annotation. +For Ingress objects, ExternalDNS will attempt to discover the target hostname of the relevant Ingress Controller automatically. If you are using an Ingress Controller that is not listed above you may have issues with ExternalDNS not discovering Endpoints and consequently not creating any DNS records. As a workaround, it is possible to force create an Endpoint by manually specifying a target host/IP for the records to be created by setting the annotation `external-dns.alpha.kubernetes.io/target` in the Ingress object. Another reason you may want to override the ingress hostname or IP address is if you have an external mechanism for handling failover across ingress endpoints. Possible scenarios for this would include using [keepalived-vip](https://github.com/kubernetes/contrib/tree/HEAD/keepalived-vip) to manage failover faster than DNS TTLs might expire. From 599590c1410bd64b6ea302f8d167b2f1ce988657 Mon Sep 17 00:00:00 2001 From: Gabriel Martinez Date: Thu, 11 May 2023 12:05:54 +0100 Subject: [PATCH 069/154] add AAAA tests --- source/service_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/source/service_test.go b/source/service_test.go index 970ae28452..0dd2983ba6 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -1389,6 +1389,20 @@ func TestClusterIpServices(t *testing.T) { {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org"}}, }, }, + { + title: "target annotated ClusterIp services return an endpoint with the specified AAAA", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "2001:DB8::1", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1"}}, + }, + }, { title: "multiple target annotated ClusterIp services return an endpoint with the specified CNAMES", svcNamespace: "testing", @@ -1403,6 +1417,21 @@ func TestClusterIpServices(t *testing.T) { {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org", "baz.example.org"}}, }, }, + { + title: "multiple target annotated ClusterIp services return two endpoints with the specified CNAMES and AAAA", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeClusterIP, + annotations: map[string]string{ + hostnameAnnotationKey: "foo.example.org.", + targetAnnotationKey: "bar.example.org.,baz.example.org.,2001:DB8::1", + }, + clusterIP: "1.2.3.4", + expected: []*endpoint.Endpoint{ + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"bar.example.org", "baz.example.org"}}, + {DNSName: "foo.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1"}}, + }, + }, { title: "hostname annotated ClusterIp services are ignored", svcNamespace: "testing", From f385139abcfb2ea4ed1ea19df18720f078cabb3a Mon Sep 17 00:00:00 2001 From: Antoine Bardoux Date: Fri, 12 May 2023 12:16:08 +0200 Subject: [PATCH 070/154] Allow multiple hostnames in internal annotation for pods --- source/pod.go | 47 +++++++++++++++++++++++++++++----------------- source/pod_test.go | 40 +++++++++++++++++++++++++++++++++++++++ source/source.go | 8 ++++++-- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/source/pod.go b/source/pod.go index 123468539f..912879b95c 100644 --- a/source/pod.go +++ b/source/pod.go @@ -89,27 +89,17 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error continue } - if domain, ok := pod.Annotations[internalHostnameAnnotationKey]; ok { - addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) - } + if domainAnnotation, ok := pod.Annotations[internalHostnameAnnotationKey]; ok { + domainList := splitHostnameAnnotation(domainAnnotation) + for _, domain := range domainList { + addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) - if domain, ok := pod.Annotations[hostnameAnnotationKey]; ok { - node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName) - for _, address := range node.Status.Addresses { - recordType := suitableType(address.Address) - // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. - if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) { - addToEndpointMap(endpointMap, domain, recordType, address.Address) - } } } - if ps.compatibility == "kops-dns-controller" { - if domain, ok := pod.Annotations[kopsDNSControllerInternalHostnameAnnotationKey]; ok { - addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) - } - - if domain, ok := pod.Annotations[kopsDNSControllerHostnameAnnotationKey]; ok { + if domainAnnotation, ok := pod.Annotations[hostnameAnnotationKey]; ok { + domainList := splitHostnameAnnotation(domainAnnotation) + for _, domain := range domainList { node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName) for _, address := range node.Status.Addresses { recordType := suitableType(address.Address) @@ -120,6 +110,29 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error } } } + + if ps.compatibility == "kops-dns-controller" { + if domainAnnotation, ok := pod.Annotations[kopsDNSControllerInternalHostnameAnnotationKey]; ok { + domainList := splitHostnameAnnotation(domainAnnotation) + for _, domain := range domainList { + addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) + } + } + + if domainAnnotation, ok := pod.Annotations[kopsDNSControllerHostnameAnnotationKey]; ok { + domainList := splitHostnameAnnotation(domainAnnotation) + for _, domain := range domainList { + node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName) + for _, address := range node.Status.Addresses { + recordType := suitableType(address.Address) + // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. + if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) { + addToEndpointMap(endpointMap, domain, recordType, address.Address) + } + } + } + } + } } endpoints := []*endpoint.Endpoint{} for key, targets := range endpointMap { diff --git a/source/pod_test.go b/source/pod_test.go index 5a57aedc26..549a9ebf90 100644 --- a/source/pod_test.go +++ b/source/pod_test.go @@ -526,6 +526,46 @@ func TestPodSource(t *testing.T) { }, }, }, + { + "split record for internal hostname annotation", + "", + "", + []*endpoint.Endpoint{ + {DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA}, + {DNSName: "internal.b.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA}, + }, + false, + []*corev1.Node{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node1", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + {Type: corev1.NodeInternalIP, Address: "10.0.1.1"}, + }, + }, + }, + }, + []*corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod1", + Namespace: "kube-system", + Annotations: map[string]string{ + internalHostnameAnnotationKey: "internal.a.foo.example.org,internal.b.foo.example.org", + }, + }, + Spec: corev1.PodSpec{ + HostNetwork: true, + NodeName: "my-node1", + }, + Status: corev1.PodStatus{ + PodIP: "10.0.1.1", + }, + }, + }, + }, } { tc := tc t.Run(tc.title, func(t *testing.T) { diff --git a/source/source.go b/source/source.go index 91b83bb4fc..e63c511bae 100644 --- a/source/source.go +++ b/source/source.go @@ -157,7 +157,7 @@ func getHostnamesFromAnnotations(annotations map[string]string) []string { if !exists { return nil } - return strings.Split(strings.Replace(hostnameAnnotation, " ", "", -1), ",") + return splitHostnameAnnotation(hostnameAnnotation) } func getAccessFromAnnotations(annotations map[string]string) string { @@ -173,7 +173,11 @@ func getInternalHostnamesFromAnnotations(annotations map[string]string) []string if !exists { return nil } - return strings.Split(strings.Replace(internalHostnameAnnotation, " ", "", -1), ",") + return splitHostnameAnnotation(internalHostnameAnnotation) +} + +func splitHostnameAnnotation(annotation string) []string { + return strings.Split(strings.Replace(annotation, " ", "", -1), ",") } func getAliasFromAnnotations(annotations map[string]string) bool { From 65b1fd71313f10ee6f3fc355c17292a1e59f069c Mon Sep 17 00:00:00 2001 From: Maksym Pylypenko Date: Fri, 12 May 2023 15:37:07 +0300 Subject: [PATCH 071/154] Add Canonical Hosted Zone IDs for ELB/NLB in eu-south-2 (Spain) AWS region --- provider/aws/aws.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 5f7457420e..935edffd3b 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -86,6 +86,7 @@ var canonicalHostedZones = map[string]string{ "eu-west-3.elb.amazonaws.com": "Z3Q77PNBQS71R4", "eu-north-1.elb.amazonaws.com": "Z23TAZ6LKFMNIO", "eu-south-1.elb.amazonaws.com": "Z3ULH7SSC9OV64", + "eu-south-2.elb.amazonaws.com": "Z0956581394HF5D5LXGAP", "sa-east-1.elb.amazonaws.com": "Z2P70J7HTTTPLU", "cn-north-1.elb.amazonaws.com.cn": "Z1GDH35T77C1KE", "cn-northwest-1.elb.amazonaws.com.cn": "ZM7IZAIOVVDZF", @@ -115,6 +116,7 @@ var canonicalHostedZones = map[string]string{ "elb.eu-west-3.amazonaws.com": "Z1CMS0P5QUZ6D5", "elb.eu-north-1.amazonaws.com": "Z1UDT6IFJ4EJM", "elb.eu-south-1.amazonaws.com": "Z23146JA1KNAFP", + "elb.eu-south-2.amazonaws.com": "Z1011216NVTVYADP1SSV", "elb.sa-east-1.amazonaws.com": "ZTK26PT1VY4CU", "elb.cn-north-1.amazonaws.com.cn": "Z3QFB96KMJ7ED6", "elb.cn-northwest-1.amazonaws.com.cn": "ZQEIKTCZ8352D", From a7992331251983e9566c0dcc817b75822a80dfab Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Fri, 12 May 2023 08:20:52 -0700 Subject: [PATCH 072/154] Refactor route53 test initial state Makes tests cover errors in conversion between endpoints and records and allows testing of records that can't be generated from an endpoint. --- provider/aws/aws_test.go | 618 ++++++++++++++++++++++++++++++++------- 1 file changed, 505 insertions(+), 113 deletions(-) diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 91ceb8a188..84d63138cf 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -304,7 +304,7 @@ func TestAWSZones(t *testing.T) { {"zone id filter", provider.NewZoneIDFilter([]string{"/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneTypeFilter(""), provider.NewZoneTagFilter([]string{}), privateZones}, {"tag filter", provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), provider.NewZoneTagFilter([]string{"zone=3"}), privateZones}, } { - provider, _ := newAWSProviderWithTagFilter(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneIDFilter, ti.zoneTypeFilter, ti.zoneTagFilter, defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProviderWithTagFilter(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), ti.zoneIDFilter, ti.zoneTypeFilter, ti.zoneTagFilter, defaultEvaluateTargetHealth, false, nil) zones, err := provider.Zones(context.Background()) require.NoError(t, err) @@ -337,26 +337,158 @@ func TestAWSRecordsFilter(t *testing.T) { } func TestAWSRecords(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), false, false, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpoint("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), - endpoint.NewEndpoint("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), - endpoint.NewEndpoint("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), - endpoint.NewEndpointWithTTL("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("prefix-*.wildcard.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeTXT, endpoint.TTL(recordTTL), "random"), - endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20"), - endpoint.NewEndpointWithTTL("latency-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificRegion, "us-east-1"), - endpoint.NewEndpointWithTTL("failover-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificFailover, "PRIMARY"), - endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), - endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), - endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), - endpoint.NewEndpointWithTTL("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, "NY"), - endpoint.NewEndpoint("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), - endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), - endpoint.NewEndpointWithTTL("mail.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), false, false, []*route53.ResourceRecordSet{ + { + Name: aws.String("list-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("list-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("list-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(false), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("*.wildcard-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(false), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("list-test-alias-evaluate.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("list-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("prefix-*.wildcard.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeTxt), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("random")}}, + }, + { + Name: aws.String("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set-1"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("weight-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("4.3.2.1")}}, + SetIdentifier: aws.String("test-set-2"), + Weight: aws.Int64(20), + }, + { + Name: aws.String("latency-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set"), + Region: aws.String("us-east-1"), + }, + { + Name: aws.String("failover-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set"), + Failover: aws.String("PRIMARY"), + }, + { + Name: aws.String("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set"), + MultiValueAnswer: aws.Bool(true), + }, + { + Name: aws.String("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set-1"), + GeoLocation: &route53.GeoLocation{ + ContinentCode: aws.String("EU"), + }, + }, + { + Name: aws.String("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("4.3.2.1")}}, + SetIdentifier: aws.String("test-set-2"), + GeoLocation: &route53.GeoLocation{ + CountryCode: aws.String("DE"), + }, + }, + { + Name: aws.String("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("test-set-1"), + GeoLocation: &route53.GeoLocation{ + SubdivisionCode: aws.String("NY"), + }, + }, + { + Name: aws.String("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.example.com")}}, + SetIdentifier: aws.String("test-set-1"), + HealthCheckId: aws.String("foo-bar-healthcheck-id"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("4.3.2.1")}}, + SetIdentifier: aws.String("test-set-2"), + HealthCheckId: aws.String("abc-def-healthcheck-id"), + Weight: aws.Int64(20), + }, + { + Name: aws.String("mail.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.example.com")}, {Value: aws.String("20 mailhost2.example.com")}}, + }, }) records, err := provider.Records(context.Background()) @@ -386,7 +518,7 @@ func TestAWSRecords(t *testing.T) { } func TestAWSAdjustEndpoints(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) records := []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), @@ -411,7 +543,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { func TestAWSCreateRecords(t *testing.T) { customTTL := endpoint.TTL(60) - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) records := []*endpoint.Endpoint{ endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "1.2.3.4"), @@ -442,13 +574,43 @@ func TestAWSCreateRecords(t *testing.T) { } func TestAWSUpdateRecords(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com"), + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*route53.ResourceRecordSet{ + { + Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.1.1.1")}}, + }, + { + Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.elb.amazonaws.com")}}, + }, + { + Name: aws.String("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.foo.elb.amazonaws.com")}}, + }, }) currentRecords := []*endpoint.Endpoint{ @@ -484,7 +646,67 @@ func TestAWSUpdateRecords(t *testing.T) { } func TestAWSDeleteRecords(t *testing.T) { - originalEndpoints := []*endpoint.Endpoint{ + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), false, false, []*route53.ResourceRecordSet{ + { + Name: aws.String("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("baz.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(false), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("delete-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("zone-2.ext-dns-test-2.teapot.zalan.do."), + }, + }, + { + Name: aws.String("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.foo.elb.amazonaws.com")}, {Value: aws.String("20 mailhost2.foo.elb.amazonaws.com")}}, + }, + }) + + require.NoError(t, provider.DeleteRecords(context.Background(), []*endpoint.Endpoint{ endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"), @@ -493,11 +715,7 @@ func TestAWSDeleteRecords(t *testing.T) { endpoint.NewEndpoint("delete-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "delete-test.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificTargetHostedZone, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), endpoint.NewEndpointWithTTL("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), endpoint.NewEndpoint("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), - } - - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), false, false, originalEndpoints) - - require.NoError(t, provider.DeleteRecords(context.Background(), originalEndpoints)) + })) records, err := provider.Records(context.Background()) @@ -522,26 +740,132 @@ func TestAWSApplyChanges(t *testing.T) { } for _, tt := range tests { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), - endpoint.NewEndpointWithTTL("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), - endpoint.NewEndpointWithTTL("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("weighted-to-simple").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("before").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost2.bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "30 mailhost1.foo.elb.amazonaws.com"), + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*route53.ResourceRecordSet{ + { + Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.1.1.1")}}, + }, + { + Name: aws.String("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}}, + }, + { + Name: aws.String("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("weighted-to-simple"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("policy-change"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("before"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("no-change"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost2.bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("30 mailhost1.foo.elb.amazonaws.com")}}, + }, }) createRecords := []*endpoint.Endpoint{ @@ -638,23 +962,88 @@ func TestAWSApplyChanges(t *testing.T) { } func TestAWSApplyChangesDryRun(t *testing.T) { - originalEndpoints := []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mail.foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mail.bar.elb.amazonaws.com"), + originalRecords := []*route53.ResourceRecordSet{ + { + Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.1.1.1")}}, + }, + { + Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("qux.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}}, + }, + { + Name: aws.String("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("20 mail.foo.elb.amazonaws.com")}}, + }, + { + Name: aws.String("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mail.bar.elb.amazonaws.com")}}, + }, } - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, true, originalEndpoints) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, true, originalRecords) createRecords := []*endpoint.Endpoint{ endpoint.NewEndpoint("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), @@ -707,7 +1096,21 @@ func TestAWSApplyChangesDryRun(t *testing.T) { records, err := provider.Records(ctx) require.NoError(t, err) - validateEndpoints(t, records, originalEndpoints) + validateEndpoints(t, records, []*endpoint.Endpoint{ + endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), + endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), + endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), + endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), + endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), + endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpointWithTTL("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), + endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mail.foo.elb.amazonaws.com"), + endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mail.bar.elb.amazonaws.com"), + }) } func TestAWSChangesByZones(t *testing.T) { @@ -828,7 +1231,7 @@ func TestAWSChangesByZones(t *testing.T) { } func TestAWSsubmitChanges(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) const subnets = 16 const hosts = defaultBatchChangeSize / subnets @@ -857,7 +1260,7 @@ func TestAWSsubmitChanges(t *testing.T) { } func TestAWSsubmitChangesError(t *testing.T) { - provider, clientStub := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, clientStub := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) clientStub.MockMethod("ChangeResourceRecordSets", mock.Anything).Return(nil, fmt.Errorf("Mock route53 failure")) ctx := context.Background() @@ -871,7 +1274,7 @@ func TestAWSsubmitChangesError(t *testing.T) { } func TestAWSsubmitChangesRetryOnError(t *testing.T) { - provider, clientStub := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, clientStub := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) ctx := context.Background() zones, err := provider.Zones(ctx) @@ -1066,7 +1469,7 @@ func validateAWSChangeRecord(t *testing.T, record *Route53Change, expected *Rout } func TestAWSCreateRecordsWithCNAME(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) records := []*endpoint.Endpoint{ {DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do", Targets: endpoint.Targets{"foo.example.org"}, RecordType: endpoint.RecordTypeCNAME}, @@ -1096,7 +1499,7 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) { "false": false, "": false, } { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) // Test dualstack and ipv4 load balancer targets records := []*endpoint.Endpoint{ @@ -1312,22 +1715,33 @@ func createAWSZone(t *testing.T, provider *AWSProvider, zone *route53.HostedZone } } -func setupAWSRecords(t *testing.T, provider *AWSProvider, endpoints []*endpoint.Endpoint) { - clearAWSRecords(t, provider, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do.") - clearAWSRecords(t, provider, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do.") - clearAWSRecords(t, provider, "/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do.") +func setAWSRecords(t *testing.T, provider *AWSProvider, records []*route53.ResourceRecordSet) { + dryRun := provider.dryRun + provider.dryRun = false + defer func() { + provider.dryRun = dryRun + }() ctx := context.Background() - records, err := provider.Records(ctx) + endpoints, err := provider.Records(ctx) require.NoError(t, err) - validateEndpoints(t, records, []*endpoint.Endpoint{}) + validateEndpoints(t, endpoints, []*endpoint.Endpoint{}) - require.NoError(t, provider.CreateRecords(context.Background(), endpoints)) + var changes Route53Changes + for _, record := range records { + changes = append(changes, &Route53Change{ + Change: route53.Change{ + Action: aws.String(route53.ChangeActionCreate), + ResourceRecordSet: record, + }, + }) + } - escapeAWSRecords(t, provider, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do.") - escapeAWSRecords(t, provider, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do.") - escapeAWSRecords(t, provider, "/hostedzone/zone-3.ext-dns-test-2.teapot.zalan.do.") + zones, err := provider.Zones(ctx) + require.NoError(t, err) + err = provider.submitChanges(ctx, changes, zones) + require.NoError(t, err) _, err = provider.Records(ctx) require.NoError(t, err) @@ -1346,28 +1760,6 @@ func listAWSRecords(t *testing.T, client Route53API, zone string) []*route53.Res return recordSets } -func clearAWSRecords(t *testing.T, provider *AWSProvider, zone string) { - recordSets := listAWSRecords(t, provider.client, zone) - - changes := make([]*route53.Change, 0, len(recordSets)) - for _, recordSet := range recordSets { - changes = append(changes, &route53.Change{ - Action: aws.String(route53.ChangeActionDelete), - ResourceRecordSet: recordSet, - }) - } - - if len(changes) != 0 { - _, err := provider.client.ChangeResourceRecordSetsWithContext(context.Background(), &route53.ChangeResourceRecordSetsInput{ - HostedZoneId: aws.String(zone), - ChangeBatch: &route53.ChangeBatch{ - Changes: changes, - }, - }) - require.NoError(t, err) - } -} - // Route53 stores wildcards escaped: http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html?shortFooter=true#domain-name-format-asterisk func escapeAWSRecords(t *testing.T, provider *AWSProvider, zone string) { recordSets := listAWSRecords(t, provider.client, zone) @@ -1391,11 +1783,11 @@ func escapeAWSRecords(t *testing.T, provider *AWSProvider, zone string) { } } -func newAWSProvider(t *testing.T, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, zoneTypeFilter provider.ZoneTypeFilter, evaluateTargetHealth, dryRun bool, records []*endpoint.Endpoint) (*AWSProvider, *Route53APIStub) { +func newAWSProvider(t *testing.T, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, zoneTypeFilter provider.ZoneTypeFilter, evaluateTargetHealth, dryRun bool, records []*route53.ResourceRecordSet) (*AWSProvider, *Route53APIStub) { return newAWSProviderWithTagFilter(t, domainFilter, zoneIDFilter, zoneTypeFilter, provider.NewZoneTagFilter([]string{}), evaluateTargetHealth, dryRun, records) } -func newAWSProviderWithTagFilter(t *testing.T, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, zoneTypeFilter provider.ZoneTypeFilter, zoneTagFilter provider.ZoneTagFilter, evaluateTargetHealth, dryRun bool, records []*endpoint.Endpoint) (*AWSProvider, *Route53APIStub) { +func newAWSProviderWithTagFilter(t *testing.T, domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, zoneTypeFilter provider.ZoneTypeFilter, zoneTagFilter provider.ZoneTagFilter, evaluateTargetHealth, dryRun bool, records []*route53.ResourceRecordSet) (*AWSProvider, *Route53APIStub) { client := NewRoute53APIStub(t) provider := &AWSProvider{ @@ -1439,7 +1831,7 @@ func newAWSProviderWithTagFilter(t *testing.T, domainFilter endpoint.DomainFilte setupZoneTags(provider.client.(*Route53APIStub)) - setupAWSRecords(t, provider, records) + setAWSRecords(t, provider, records) provider.dryRun = dryRun @@ -1494,7 +1886,7 @@ func containsRecordWithDNSName(records []*endpoint.Endpoint, dnsName string) boo } func TestRequiresDeleteCreate(t *testing.T) { - provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"foo.bar."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, []*endpoint.Endpoint{}) + provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"foo.bar."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) oldRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8") newRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar") From 10a6a04e47dc743531449113369d2fca2ef6864c Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Fri, 12 May 2023 14:05:51 -0700 Subject: [PATCH 073/154] Refactor route53 test assertions Makes relevant tests verify the precise resulting route53 records --- provider/aws/aws_test.go | 299 ++++++++++++++++++++++++++++++--------- 1 file changed, 231 insertions(+), 68 deletions(-) diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 84d63138cf..7382b54f35 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -558,18 +558,63 @@ func TestAWSCreateRecords(t *testing.T) { require.NoError(t, provider.CreateRecords(context.Background(), records)) - records, err := provider.Records(context.Background()) - require.NoError(t, err) - - validateEndpoints(t, records, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("create-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("create-test-custom-ttl.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, customTTL, "172.17.0.1"), - endpoint.NewEndpointWithTTL("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com"), - endpoint.NewEndpointWithTTL("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), - endpoint.NewEndpointWithTTL("create-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), - endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("create-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("create-test-custom-ttl.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(60), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("172.17.0.1")}}, + }, + { + Name: aws.String("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.example.com")}}, + }, + { + Name: aws.String("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.eu-central-1.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("Z215JYRZR1TBD5"), + }, + }, + { + Name: aws.String("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.example.com")}, {Value: aws.String("20 mailhost2.example.com")}}, + }, + }) + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("create-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("create-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("alias-target.zone-2.ext-dns-test-2.teapot.zalan.do."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("zone-2.ext-dns-test-2.teapot.zalan.do."), + }, + }, }) } @@ -632,16 +677,45 @@ func TestAWSUpdateRecords(t *testing.T) { require.NoError(t, provider.UpdateRecords(context.Background(), updatedRecords, currentRecords)) - records, err := provider.Records(context.Background()) - require.NoError(t, err) - - validateEndpoints(t, records, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("bar.elb.amazonaws.com")}}, + }, + { + Name: aws.String("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}}, + }, + { + Name: aws.String("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.foo.elb.amazonaws.com")}, {Value: aws.String("20 mailhost2.foo.elb.amazonaws.com")}}, + }, + }) + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("4.3.2.1")}}, + }, }) } @@ -717,11 +791,8 @@ func TestAWSDeleteRecords(t *testing.T) { endpoint.NewEndpoint("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), })) - records, err := provider.Records(context.Background()) - - require.NoError(t, err) - - validateEndpoints(t, records, []*endpoint.Endpoint{}) + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{}) + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{}) } func TestAWSApplyChanges(t *testing.T) { @@ -934,29 +1005,134 @@ func TestAWSApplyChanges(t *testing.T) { assert.Equal(t, 1, counter.calls["ListHostedZonesPages"], tt.name) assert.Equal(t, tt.listRRSets, counter.calls["ListResourceRecordSetsPages"], tt.name) - records, err := provider.Records(ctx) - require.NoError(t, err, tt.name) - - validateEndpoints(t, records, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("create-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("create-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), - endpoint.NewEndpointWithTTL("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "my-internal-host.example.com"), - endpoint.NewEndpointWithTTL("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), - endpoint.NewEndpointWithTTL("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("simple-to-weighted").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("policy-change").WithProviderSpecific(providerSpecificRegion, "us-east-1"), - endpoint.NewEndpointWithTTL("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("after").WithProviderSpecific(providerSpecificWeight, "10"), - endpoint.NewEndpointWithTTL("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("no-change").WithProviderSpecific(providerSpecificWeight, "20"), - endpoint.NewEndpointWithTTL("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mailhost3.foo.elb.amazonaws.com"), + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("create-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}}, + }, + { + Name: aws.String("update-test.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + AliasTarget: &route53.AliasTarget{ + DNSName: aws.String("foo.elb.amazonaws.com."), + EvaluateTargetHealth: aws.Bool(true), + HostedZoneId: aws.String("zone-1.ext-dns-test-2.teapot.zalan.do."), + }, + }, + { + Name: aws.String("update-test-alias-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("my-internal-host.example.com")}}, + }, + { + Name: aws.String("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("baz.elb.amazonaws.com")}}, + }, + { + Name: aws.String("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("foo.elb.amazonaws.com")}}, + }, + { + Name: aws.String("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeCname), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("baz.elb.amazonaws.com")}}, + }, + { + Name: aws.String("weighted-to-simple.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + }, + { + Name: aws.String("simple-to-weighted.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("simple-to-weighted"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("policy-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("policy-change"), + Region: aws.String("us-east-1"), + }, + { + Name: aws.String("set-identifier-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("after"), + Weight: aws.Int64(10), + }, + { + Name: aws.String("set-identifier-no-change.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, + SetIdentifier: aws.String("no-change"), + Weight: aws.Int64(20), + }, + { + Name: aws.String("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("10 mailhost1.foo.elb.amazonaws.com")}}, + }, + }) + validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ + { + Name: aws.String("create-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("4.3.2.1")}}, + }, + { + Name: aws.String("create-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("8.8.8.8")}, {Value: aws.String("8.8.4.4")}}, + }, + { + Name: aws.String("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}, {Value: aws.String("4.3.2.1")}}, + }, + { + Name: aws.String("update-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do."), + Type: aws.String(route53.RRTypeMx), + TTL: aws.Int64(recordTTL), + ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("20 mailhost3.foo.elb.amazonaws.com")}}, + }, }) } } @@ -1093,24 +1269,11 @@ func TestAWSApplyChangesDryRun(t *testing.T) { require.NoError(t, provider.ApplyChanges(ctx, changes)) - records, err := provider.Records(ctx) - require.NoError(t, err) - - validateEndpoints(t, records, []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("update-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("update-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.4.4"), - endpoint.NewEndpointWithTTL("update-test-a-to-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.1.1.1"), - endpoint.NewEndpointWithTTL("update-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "qux.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("update-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpointWithTTL("delete-test-multiple.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4", "4.3.2.1"), - endpoint.NewEndpointWithTTL("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "20 mail.foo.elb.amazonaws.com"), - endpoint.NewEndpointWithTTL("delete-test-mx.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mail.bar.elb.amazonaws.com"), - }) + validateRecords(t, + append( + listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), + listAWSRecords(t, provider.client, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do.")...), + originalRecords) } func TestAWSChangesByZones(t *testing.T) { From b17506cfa39107d9619b2763a931ee6fe7faca66 Mon Sep 17 00:00:00 2001 From: Antoine Bardoux Date: Tue, 16 May 2023 15:43:28 +0200 Subject: [PATCH 074/154] Remove unnecessary trailing newline --- source/pod.go | 1 - 1 file changed, 1 deletion(-) diff --git a/source/pod.go b/source/pod.go index 912879b95c..e399a8906a 100644 --- a/source/pod.go +++ b/source/pod.go @@ -93,7 +93,6 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error domainList := splitHostnameAnnotation(domainAnnotation) for _, domain := range domainList { addToEndpointMap(endpointMap, domain, suitableType(pod.Status.PodIP), pod.Status.PodIP) - } } From 83d58fae03f514a789230101e95e1096871d5d32 Mon Sep 17 00:00:00 2001 From: Jonas-Taha El Sesiy Date: Tue, 16 May 2023 08:46:54 -0700 Subject: [PATCH 075/154] Remove UpdateOld changeset for Azure The underlying SDK uses `recordSetsClient.CreateOrUpdate()` [doc](https://docs.microsoft.com/en-us/rest/api/dns/record-sets/create-or-update) which allows us to exclusively rely on UpdateNew for record set updates. As a result, we're no longer running the risk of zone update failures causing outages as outlined in #2918 Fix https://github.com/kubernetes-sigs/external-dns/issues/2918 --- provider/azure/azure.go | 4 ---- provider/azure/azure_private_dns.go | 4 ---- provider/azure/azure_privatedns_test.go | 3 --- provider/azure/azure_test.go | 5 ----- 4 files changed, 16 deletions(-) diff --git a/provider/azure/azure.go b/provider/azure/azure.go index b56a21320a..bca9c841d6 100644 --- a/provider/azure/azure.go +++ b/provider/azure/azure.go @@ -250,10 +250,6 @@ func (p *AzureProvider) mapChanges(zones []dns.Zone, changes *plan.Changes) (azu mapChange(deleted, change) } - for _, change := range changes.UpdateOld { - mapChange(deleted, change) - } - for _, change := range changes.Create { mapChange(updated, change) } diff --git a/provider/azure/azure_private_dns.go b/provider/azure/azure_private_dns.go index e3ab40c48e..ee2e478bd1 100644 --- a/provider/azure/azure_private_dns.go +++ b/provider/azure/azure_private_dns.go @@ -237,10 +237,6 @@ func (p *AzurePrivateDNSProvider) mapChanges(zones []privatedns.PrivateZone, cha mapChange(deleted, change) } - for _, change := range changes.UpdateOld { - mapChange(deleted, change) - } - for _, change := range changes.Create { mapChange(updated, change) } diff --git a/provider/azure/azure_privatedns_test.go b/provider/azure/azure_privatedns_test.go index e728659c4a..061b0f4d6b 100644 --- a/provider/azure/azure_privatedns_test.go +++ b/provider/azure/azure_privatedns_test.go @@ -342,11 +342,8 @@ func TestAzurePrivateDNSApplyChanges(t *testing.T) { testAzurePrivateDNSApplyChangesInternal(t, false, &recordsClient) validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{ - endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, ""), - endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, ""), endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, ""), endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, ""), - endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, ""), }) validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ diff --git a/provider/azure/azure_test.go b/provider/azure/azure_test.go index 050ab3d923..ba831586c2 100644 --- a/provider/azure/azure_test.go +++ b/provider/azure/azure_test.go @@ -349,11 +349,8 @@ func TestAzureApplyChanges(t *testing.T) { testAzureApplyChangesInternal(t, false, &recordsClient) validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{ - endpoint.NewEndpoint("old.example.com", endpoint.RecordTypeA, ""), - endpoint.NewEndpoint("oldcname.example.com", endpoint.RecordTypeCNAME, ""), endpoint.NewEndpoint("deleted.example.com", endpoint.RecordTypeA, ""), endpoint.NewEndpoint("deletedcname.example.com", endpoint.RecordTypeCNAME, ""), - endpoint.NewEndpoint("oldmail.example.com", endpoint.RecordTypeMX, ""), }) validateAzureEndpoints(t, recordsClient.updatedEndpoints, []*endpoint.Endpoint{ @@ -508,8 +505,6 @@ func TestAzureApplyChangesZoneName(t *testing.T) { testAzureApplyChangesInternalZoneName(t, false, &recordsClient) validateAzureEndpoints(t, recordsClient.deletedEndpoints, []*endpoint.Endpoint{ - endpoint.NewEndpoint("old.foo.example.com", endpoint.RecordTypeA, ""), - endpoint.NewEndpoint("oldcname.foo.example.com", endpoint.RecordTypeCNAME, ""), endpoint.NewEndpoint("deleted.foo.example.com", endpoint.RecordTypeA, ""), endpoint.NewEndpoint("deletedcname.foo.example.com", endpoint.RecordTypeCNAME, ""), }) From a8d0c4dc1d6c29ab9a889c582155b4be616f9a94 Mon Sep 17 00:00:00 2001 From: nitrocode <7775707+nitrocode@users.noreply.github.com> Date: Tue, 23 May 2023 17:08:09 -0500 Subject: [PATCH 076/154] chore(deps): bump libcrypto3 and libssl3 3.0.8-r4 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8590ad6332..db7d8dcca7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ COPY . . FROM alpine:3.18 -RUN apk update && apk add "libcrypto3>=3.0.8-r1" "libssl3>=3.0.8-r1" && rm -rf /var/cache/apt/* +RUN apk update && apk add "libcrypto3>=3.0.8-r4" "libssl3>=3.0.8-r4" && rm -rf /var/cache/apt/* COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=builder /sigs.k8s.io/external-dns/build/external-dns /bin/external-dns From 34ab4055daf240d8284940a80c5d43e3d498fcae Mon Sep 17 00:00:00 2001 From: aoz-turk Date: Wed, 24 May 2023 14:46:22 +0300 Subject: [PATCH 077/154] Add no-change info log for cloudflare provider --- provider/cloudflare/cloudflare.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provider/cloudflare/cloudflare.go b/provider/cloudflare/cloudflare.go index 0623ca2a05..5a6e711e1c 100644 --- a/provider/cloudflare/cloudflare.go +++ b/provider/cloudflare/cloudflare.go @@ -297,6 +297,7 @@ func (p *CloudFlareProvider) PropertyValuesEqual(name string, previous string, c func (p *CloudFlareProvider) submitChanges(ctx context.Context, changes []*cloudFlareChange) error { // return early if there is nothing to change if len(changes) == 0 { + log.Info("All records are already up to date") return nil } From ca5d74d5453e0c5673e6c09c960b85d394f94649 Mon Sep 17 00:00:00 2001 From: megum1n Date: Mon, 29 May 2023 01:05:47 +0200 Subject: [PATCH 078/154] Add separate test for metadata static virtual host --- source/gloo_proxy_test.go | 161 ++++++++++++++++++++++++++++++++------ 1 file changed, 138 insertions(+), 23 deletions(-) diff --git a/source/gloo_proxy_test.go b/source/gloo_proxy_test.go index 2df0246666..385d1a9692 100644 --- a/source/gloo_proxy_test.go +++ b/source/gloo_proxy_test.go @@ -63,17 +63,6 @@ var internalProxy = proxy{ }, }, }, - MetadataStatic: proxyVirtualHostMetadataStatic{ - Source: []proxyVirtualHostMetadataStaticSource{ - { - ResourceKind: "*v1.Unknown", - ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ - Name: "my-unknown-svc", - Namespace: "unknown", - }, - }, - }, - }, }, { Domains: []string{"c.test"}, @@ -86,17 +75,6 @@ var internalProxy = proxy{ }, }, }, - MetadataStatic: proxyVirtualHostMetadataStatic{ - Source: []proxyVirtualHostMetadataStaticSource{ - { - ResourceKind: "*v1.VirtualService", - ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ - Name: "my-internal-svc", - Namespace: "internal", - }, - }, - }, - }, }, }, }, @@ -233,6 +211,97 @@ var externalProxySource = metav1.PartialObjectMetadata{ }, } +// Proxy with metadata static test +var proxyMetadataStatic = proxy{ + TypeMeta: metav1.TypeMeta{ + APIVersion: proxyGVR.GroupVersion().String(), + Kind: "Proxy", + }, + Metadata: metav1.ObjectMeta{ + Name: "internal-static", + Namespace: defaultGlooNamespace, + }, + Spec: proxySpec{ + Listeners: []proxySpecListener{ + { + HTTPListener: proxySpecHTTPListener{ + VirtualHosts: []proxyVirtualHost{ + { + Domains: []string{"f.test", "g.test"}, + MetadataStatic: proxyVirtualHostMetadataStatic{ + Source: []proxyVirtualHostMetadataStaticSource{ + { + ResourceKind: "*v1.Unknown", + ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ + Name: "my-unknown-svc", + Namespace: "unknown", + }, + }, + }, + }, + }, + { + Domains: []string{"h.test"}, + MetadataStatic: proxyVirtualHostMetadataStatic{ + Source: []proxyVirtualHostMetadataStaticSource{ + { + ResourceKind: "*v1.VirtualService", + ResourceRef: proxyVirtualHostMetadataSourceResourceRef{ + Name: "my-internal-static-svc", + Namespace: "internal-static", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, +} + +var proxyMetadataStaticSvc = corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: proxyMetadataStatic.Metadata.Name, + Namespace: proxyMetadataStatic.Metadata.Namespace, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + }, + Status: corev1.ServiceStatus{ + LoadBalancer: corev1.LoadBalancerStatus{ + Ingress: []corev1.LoadBalancerIngress{ + { + IP: "203.0.115.1", + }, + { + IP: "203.0.115.2", + }, + { + IP: "203.0.115.3", + }, + }, + }, + }, +} + +var proxyMetadataStaticSource = metav1.PartialObjectMetadata{ + TypeMeta: metav1.TypeMeta{ + APIVersion: virtualServiceGVR.GroupVersion().String(), + Kind: "VirtualService", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: proxyMetadataStatic.Spec.Listeners[0].HTTPListener.VirtualHosts[1].MetadataStatic.Source[0].ResourceRef.Name, + Namespace: proxyMetadataStatic.Spec.Listeners[0].HTTPListener.VirtualHosts[1].MetadataStatic.Source[0].ResourceRef.Namespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/ttl": "420", + "external-dns.alpha.kubernetes.io/aws-geolocation-country-code": "ES", + "external-dns.alpha.kubernetes.io/set-identifier": "identifier", + }, + }, +} + func TestGlooSource(t *testing.T) { t.Parallel() @@ -248,9 +317,11 @@ func TestGlooSource(t *testing.T) { internalProxyUnstructured := unstructured.Unstructured{} externalProxyUnstructured := unstructured.Unstructured{} + proxyMetadataStaticUnstructured := unstructured.Unstructured{} internalProxySourceUnstructured := unstructured.Unstructured{} externalProxySourceUnstructured := unstructured.Unstructured{} + proxyMetadataStaticSourceUnstructured := unstructured.Unstructured{} internalProxyAsJSON, err := json.Marshal(internalProxy) assert.NoError(t, err) @@ -258,39 +329,53 @@ func TestGlooSource(t *testing.T) { externalProxyAsJSON, err := json.Marshal(externalProxy) assert.NoError(t, err) + proxyMetadataStaticAsJSON, err := json.Marshal(proxyMetadataStatic) + assert.NoError(t, err) + internalProxySvcAsJSON, err := json.Marshal(internalProxySource) assert.NoError(t, err) externalProxySvcAsJSON, err := json.Marshal(externalProxySource) assert.NoError(t, err) + proxyMetadataStaticSvcAsJSON, err := json.Marshal(proxyMetadataStaticSource) + assert.NoError(t, err) + assert.NoError(t, internalProxyUnstructured.UnmarshalJSON(internalProxyAsJSON)) assert.NoError(t, externalProxyUnstructured.UnmarshalJSON(externalProxyAsJSON)) + assert.NoError(t, proxyMetadataStaticUnstructured.UnmarshalJSON(proxyMetadataStaticAsJSON)) assert.NoError(t, internalProxySourceUnstructured.UnmarshalJSON(internalProxySvcAsJSON)) assert.NoError(t, externalProxySourceUnstructured.UnmarshalJSON(externalProxySvcAsJSON)) + assert.NoError(t, proxyMetadataStaticSourceUnstructured.UnmarshalJSON(proxyMetadataStaticSvcAsJSON)) // Create proxy resources _, err = fakeDynamicClient.Resource(proxyGVR).Namespace(defaultGlooNamespace).Create(context.Background(), &internalProxyUnstructured, metav1.CreateOptions{}) assert.NoError(t, err) _, err = fakeDynamicClient.Resource(proxyGVR).Namespace(defaultGlooNamespace).Create(context.Background(), &externalProxyUnstructured, metav1.CreateOptions{}) assert.NoError(t, err) + _, err = fakeDynamicClient.Resource(proxyGVR).Namespace(defaultGlooNamespace).Create(context.Background(), &proxyMetadataStaticUnstructured, metav1.CreateOptions{}) + assert.NoError(t, err) // Create proxy source _, err = fakeDynamicClient.Resource(virtualServiceGVR).Namespace(internalProxySource.Namespace).Create(context.Background(), &internalProxySourceUnstructured, metav1.CreateOptions{}) assert.NoError(t, err) _, err = fakeDynamicClient.Resource(virtualServiceGVR).Namespace(externalProxySource.Namespace).Create(context.Background(), &externalProxySourceUnstructured, metav1.CreateOptions{}) assert.NoError(t, err) + _, err = fakeDynamicClient.Resource(virtualServiceGVR).Namespace(proxyMetadataStaticSource.Namespace).Create(context.Background(), &proxyMetadataStaticSourceUnstructured, metav1.CreateOptions{}) + assert.NoError(t, err) // Create proxy service resources _, err = fakeKubernetesClient.CoreV1().Services(internalProxySvc.GetNamespace()).Create(context.Background(), &internalProxySvc, metav1.CreateOptions{}) assert.NoError(t, err) _, err = fakeKubernetesClient.CoreV1().Services(externalProxySvc.GetNamespace()).Create(context.Background(), &externalProxySvc, metav1.CreateOptions{}) assert.NoError(t, err) + _, err = fakeKubernetesClient.CoreV1().Services(proxyMetadataStaticSvc.GetNamespace()).Create(context.Background(), &proxyMetadataStaticSvc, metav1.CreateOptions{}) + assert.NoError(t, err) endpoints, err := source.Endpoints(context.Background()) assert.NoError(t, err) - assert.Len(t, endpoints, 5) + assert.Len(t, endpoints, 8) assert.ElementsMatch(t, endpoints, []*endpoint.Endpoint{ { DNSName: "a.test", @@ -344,5 +429,35 @@ func TestGlooSource(t *testing.T) { }, }, }, + { + DNSName: "f.test", + Targets: []string{proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[0].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[1].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[2].IP}, + RecordType: endpoint.RecordTypeA, + RecordTTL: 0, + Labels: endpoint.Labels{}, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "g.test", + Targets: []string{proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[0].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[1].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[2].IP}, + RecordType: endpoint.RecordTypeA, + RecordTTL: 0, + Labels: endpoint.Labels{}, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "h.test", + Targets: []string{proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[0].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[1].IP, proxyMetadataStaticSvc.Status.LoadBalancer.Ingress[2].IP}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "identifier", + RecordTTL: 420, + Labels: endpoint.Labels{}, + ProviderSpecific: endpoint.ProviderSpecific{ + endpoint.ProviderSpecificProperty{ + Name: "aws/geolocation-country-code", + Value: "ES", + }, + }, + }, }) } From 3abaaeee9b64949e7ca86fea8f3da15facb8f1df Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Fri, 10 Mar 2023 04:24:43 +0100 Subject: [PATCH 079/154] fix: godaddy - handle correctly when no postfix/prefix used for TXT fix: godaddy.go - gofmt fix: linter errors --- provider/godaddy/client.go | 3 +- provider/godaddy/godaddy.go | 69 +++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/provider/godaddy/client.go b/provider/godaddy/client.go index e70589cc5b..208fe22a4f 100644 --- a/provider/godaddy/client.go +++ b/provider/godaddy/client.go @@ -29,6 +29,7 @@ import ( "time" "golang.org/x/time/rate" + "sigs.k8s.io/external-dns/pkg/apis/externaldns" ) @@ -230,7 +231,7 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) { for i := 1; i < 3 && err == nil && resp.StatusCode == 429; i++ { retryAfter, _ := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 0) - jitter := rand.Int63n(int64(retryAfter)) + jitter := rand.Int63n(retryAfter) retryAfterSec := retryAfter + jitter/2 sleepTime := time.Duration(retryAfterSec) * time.Second diff --git a/provider/godaddy/godaddy.go b/provider/godaddy/godaddy.go index 2193e5c278..0b2186ce54 100644 --- a/provider/godaddy/godaddy.go +++ b/provider/godaddy/godaddy.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -367,22 +367,6 @@ func (p *GDProvider) changeAllRecords(endpoints []gdEndpoint, zoneRecords []*gdR return nil } -func (p *GDProvider) endpointEqual(l *endpoint.Endpoint, r *endpoint.Endpoint) bool { - if l.DNSName != r.DNSName || l.RecordType!= r.RecordType { - return false - } - - if ! l.Targets.Same(r.Targets) { - return false - } - - if l.RecordTTL != r.RecordTTL { - return false - } - - return true -} - // ApplyChanges applies a given set of changes in a given zone. func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { if countTargets(changes) == 0 { @@ -404,22 +388,42 @@ func (p *GDProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) er allChanges = p.appendChange(gdDelete, changes.Delete, allChanges) - for _, recOld := range changes.UpdateOld { - for _, recNew := range changes.UpdateNew { + iOldSkip := make(map[int]bool) + iNewSkip := make(map[int]bool) + + for iOld, recOld := range changes.UpdateOld { + for iNew, recNew := range changes.UpdateNew { + if recOld.DNSName == recNew.DNSName && recOld.RecordType == recNew.RecordType { + ReplaceEndpoints := []*endpoint.Endpoint{recNew} + allChanges = p.appendChange(gdReplace, ReplaceEndpoints, allChanges) + iOldSkip[iOld] = true + iNewSkip[iNew] = true + break + } + } + } + + for iOld, recOld := range changes.UpdateOld { + _, found := iOldSkip[iOld] + if found { + continue + } + for iNew, recNew := range changes.UpdateNew { + _, found := iNewSkip[iNew] + if found { + continue + } + if recOld.DNSName != recNew.DNSName { - continue - } - - if ! p.endpointEqual(recOld, recNew) { - DeleteEndpoints := []*endpoint.Endpoint{recOld} - PatchEndpoints := []*endpoint.Endpoint{recNew} - if recOld.RecordType == recNew.RecordType { - allChanges = p.appendChange(gdReplace, PatchEndpoints, allChanges) - } else { - allChanges = p.appendChange(gdDelete, DeleteEndpoints, allChanges) - allChanges = p.appendChange(gdCreate, PatchEndpoints, allChanges) - } + continue } + + DeleteEndpoints := []*endpoint.Endpoint{recOld} + CreateEndpoints := []*endpoint.Endpoint{recNew} + allChanges = p.appendChange(gdDelete, DeleteEndpoints, allChanges) + allChanges = p.appendChange(gdCreate, CreateEndpoints, allChanges) + + break } } @@ -455,7 +459,6 @@ func (p *gdRecords) addRecord(client gdClient, endpoint endpoint.Endpoint, dnsNa return err } - } return nil @@ -493,7 +496,6 @@ func (p *gdRecords) replaceRecord(client gdClient, endpoint endpoint.Endpoint, d var response GDErrorResponse - if dryRun { log.Infof("[DryRun] - Replace record %s.%s of type %s %s", dnsName, p.zone, endpoint.RecordType, records) @@ -540,7 +542,6 @@ func (p *gdRecords) deleteRecord(client gdClient, endpoint endpoint.Endpoint, dn p.records = p.records[:len(p.records)-1] p.changed = true } - } if dryRun { From 44b182e2ac67323ab03169870381536d0aed439a Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Mon, 29 May 2023 23:08:57 +0200 Subject: [PATCH 080/154] bump kustomize version Signed-off-by: Raffaele Di Fazio --- kustomize/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kustomize/kustomization.yaml b/kustomize/kustomization.yaml index f0c516a640..5a6cb4b7e5 100644 --- a/kustomize/kustomization.yaml +++ b/kustomize/kustomization.yaml @@ -3,7 +3,7 @@ kind: Kustomization images: - name: registry.k8s.io/external-dns/external-dns - newTag: v0.13.4 + newTag: v0.13.5 resources: - ./external-dns-deployment.yaml From b7c1d9519e57211faaae2a5eceb2027c99d9e551 Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Mon, 29 May 2023 23:11:04 +0200 Subject: [PATCH 081/154] bump versions in all docs Signed-off-by: Raffaele Di Fazio --- docs/faq.md | 2 +- docs/tutorials/ANS_Group_SafeDNS.md | 4 ++-- docs/tutorials/akamai-edgedns.md | 4 ++-- docs/tutorials/alibabacloud.md | 4 ++-- docs/tutorials/aws-sd.md | 4 ++-- docs/tutorials/aws.md | 6 +++--- docs/tutorials/azure-private-dns.md | 6 +++--- docs/tutorials/azure.md | 6 +++--- docs/tutorials/bluecat.md | 4 ++-- docs/tutorials/civo.md | 4 ++-- docs/tutorials/cloudflare.md | 4 ++-- docs/tutorials/contour.md | 4 ++-- docs/tutorials/coredns.md | 4 ++-- docs/tutorials/designate.md | 4 ++-- docs/tutorials/digitalocean.md | 4 ++-- docs/tutorials/dnsimple.md | 4 ++-- docs/tutorials/dyn.md | 2 +- docs/tutorials/exoscale.md | 2 +- docs/tutorials/externalname.md | 2 +- docs/tutorials/gandi.md | 4 ++-- docs/tutorials/gateway-api.md | 2 +- docs/tutorials/gke.md | 2 +- docs/tutorials/gloo-proxy.md | 4 ++-- docs/tutorials/godaddy.md | 4 ++-- docs/tutorials/hostport.md | 4 ++-- docs/tutorials/ibmcloud.md | 4 ++-- docs/tutorials/infoblox.md | 4 ++-- docs/tutorials/istio.md | 4 ++-- docs/tutorials/kong.md | 4 ++-- docs/tutorials/linode.md | 4 ++-- docs/tutorials/nginx-ingress.md | 4 ++-- docs/tutorials/nodes.md | 4 ++-- docs/tutorials/ns1.md | 4 ++-- docs/tutorials/openshift.md | 4 ++-- docs/tutorials/oracle.md | 2 +- docs/tutorials/ovh.md | 4 ++-- docs/tutorials/pdns.md | 2 +- docs/tutorials/pihole.md | 2 +- docs/tutorials/plural.md | 4 ++-- docs/tutorials/public-private-route53.md | 4 ++-- docs/tutorials/rcodezero.md | 4 ++-- docs/tutorials/rdns.md | 4 ++-- docs/tutorials/rfc2136.md | 4 ++-- docs/tutorials/scaleway.md | 4 ++-- docs/tutorials/security-context.md | 2 +- docs/tutorials/tencentcloud.md | 2 +- docs/tutorials/transip.md | 4 ++-- docs/tutorials/ultradns.md | 4 ++-- docs/tutorials/vinyldns.md | 4 ++-- docs/tutorials/vultr.md | 4 ++-- 50 files changed, 92 insertions(+), 92 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 43731a3712..6da020c5d8 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -207,7 +207,7 @@ $ docker run \ -e EXTERNAL_DNS_SOURCE=$'service\ningress' \ -e EXTERNAL_DNS_PROVIDER=google \ -e EXTERNAL_DNS_DOMAIN_FILTER=$'foo.com\nbar.com' \ - registry.k8s.io/external-dns/external-dns:v0.13.4 + registry.k8s.io/external-dns/external-dns:v0.13.5 time="2017-08-08T14:10:26Z" level=info msg="config: &{APIServerURL: KubeConfig: Sources:[service ingress] Namespace: ... ``` diff --git a/docs/tutorials/ANS_Group_SafeDNS.md b/docs/tutorials/ANS_Group_SafeDNS.md index c60e65517b..92450495b9 100644 --- a/docs/tutorials/ANS_Group_SafeDNS.md +++ b/docs/tutorials/ANS_Group_SafeDNS.md @@ -48,7 +48,7 @@ spec: - name: external-dns # You will need to check what the latest version is yourself: # https://github.com/kubernetes-sigs/external-dns/releases - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible # (optional) limit to only example.com domains; change to match the @@ -114,7 +114,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible # (optional) limit to only example.com domains; change to match the diff --git a/docs/tutorials/akamai-edgedns.md b/docs/tutorials/akamai-edgedns.md index dd065daed0..4c88934239 100644 --- a/docs/tutorials/akamai-edgedns.md +++ b/docs/tutorials/akamai-edgedns.md @@ -57,7 +57,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # or ingress or both - --provider=akamai @@ -143,7 +143,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # or ingress or both - --provider=akamai diff --git a/docs/tutorials/alibabacloud.md b/docs/tutorials/alibabacloud.md index f7653237e4..379e13b4c5 100644 --- a/docs/tutorials/alibabacloud.md +++ b/docs/tutorials/alibabacloud.md @@ -113,7 +113,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -187,7 +187,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/aws-sd.md b/docs/tutorials/aws-sd.md index 970af7940a..c540fc7daf 100644 --- a/docs/tutorials/aws-sd.md +++ b/docs/tutorials/aws-sd.md @@ -81,7 +81,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 env: - name: AWS_REGION value: us-east-1 # put your CloudMap NameSpace region @@ -148,7 +148,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 env: - name: AWS_REGION value: us-east-1 # put your CloudMap NameSpace region diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index f77f8017f2..fb96ec3e15 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -413,7 +413,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -508,7 +508,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -961,7 +961,7 @@ A simple way to implement randomised startup is with an init container: spec: initContainers: - name: init-jitter - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 command: - /bin/sh - -c diff --git a/docs/tutorials/azure-private-dns.md b/docs/tutorials/azure-private-dns.md index 0e85d90267..218b11dff7 100644 --- a/docs/tutorials/azure-private-dns.md +++ b/docs/tutorials/azure-private-dns.md @@ -130,7 +130,7 @@ spec: spec: containers: - name: externaldns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -201,7 +201,7 @@ spec: serviceAccountName: externaldns containers: - name: externaldns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -272,7 +272,7 @@ spec: serviceAccountName: externaldns containers: - name: externaldns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/azure.md b/docs/tutorials/azure.md index b6d8850340..330c970e10 100644 --- a/docs/tutorials/azure.md +++ b/docs/tutorials/azure.md @@ -356,7 +356,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -424,7 +424,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -495,7 +495,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/bluecat.md b/docs/tutorials/bluecat.md index 4ef9c1b39a..5d386aab87 100644 --- a/docs/tutorials/bluecat.md +++ b/docs/tutorials/bluecat.md @@ -46,7 +46,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --log-level=debug - --source=service @@ -136,7 +136,7 @@ spec: secretName: bluecatconfig containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 volumeMounts: - name: bluecatconfig mountPath: "/etc/external-dns/" diff --git a/docs/tutorials/civo.md b/docs/tutorials/civo.md index efa5b6fc45..55e5f7da14 100644 --- a/docs/tutorials/civo.md +++ b/docs/tutorials/civo.md @@ -41,7 +41,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -105,7 +105,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/cloudflare.md b/docs/tutorials/cloudflare.md index 79deffeff7..869483e89e 100644 --- a/docs/tutorials/cloudflare.md +++ b/docs/tutorials/cloudflare.md @@ -56,7 +56,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -125,7 +125,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/contour.md b/docs/tutorials/contour.md index 05e392b6f8..cdb30c52e0 100644 --- a/docs/tutorials/contour.md +++ b/docs/tutorials/contour.md @@ -26,7 +26,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -102,7 +102,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/coredns.md b/docs/tutorials/coredns.md index 5cd1223f29..3ef2caf317 100644 --- a/docs/tutorials/coredns.md +++ b/docs/tutorials/coredns.md @@ -108,7 +108,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --provider=coredns @@ -175,7 +175,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --provider=coredns diff --git a/docs/tutorials/designate.md b/docs/tutorials/designate.md index e2c79bfbbf..7ed8b24b45 100644 --- a/docs/tutorials/designate.md +++ b/docs/tutorials/designate.md @@ -59,7 +59,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -136,7 +136,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/digitalocean.md b/docs/tutorials/digitalocean.md index cbad0cfe6d..a6874326f9 100644 --- a/docs/tutorials/digitalocean.md +++ b/docs/tutorials/digitalocean.md @@ -43,7 +43,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -107,7 +107,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/dnsimple.md b/docs/tutorials/dnsimple.md index 5af82f6d93..3bdce68381 100644 --- a/docs/tutorials/dnsimple.md +++ b/docs/tutorials/dnsimple.md @@ -35,7 +35,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple. @@ -100,7 +100,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone you create in DNSimple. diff --git a/docs/tutorials/dyn.md b/docs/tutorials/dyn.md index 573837bb5b..40f5c87ea2 100644 --- a/docs/tutorials/dyn.md +++ b/docs/tutorials/dyn.md @@ -43,7 +43,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --txt-prefix=_d diff --git a/docs/tutorials/exoscale.md b/docs/tutorials/exoscale.md index 047c1d6b8b..6f7dd3fbc2 100644 --- a/docs/tutorials/exoscale.md +++ b/docs/tutorials/exoscale.md @@ -41,7 +41,7 @@ spec: # serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress # or service or both - --provider=exoscale diff --git a/docs/tutorials/externalname.md b/docs/tutorials/externalname.md index c5a5600395..3604823ede 100644 --- a/docs/tutorials/externalname.md +++ b/docs/tutorials/externalname.md @@ -27,7 +27,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --log-level=debug - --source=service diff --git a/docs/tutorials/gandi.md b/docs/tutorials/gandi.md index 7f4f4036b9..7a7566e4c9 100644 --- a/docs/tutorials/gandi.md +++ b/docs/tutorials/gandi.md @@ -39,7 +39,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -103,7 +103,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/gateway-api.md b/docs/tutorials/gateway-api.md index 26ebae312f..f1f39ca690 100644 --- a/docs/tutorials/gateway-api.md +++ b/docs/tutorials/gateway-api.md @@ -72,7 +72,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: # Add desired Gateway API Route sources. - --source=gateway-httproute diff --git a/docs/tutorials/gke.md b/docs/tutorials/gke.md index d4d9e8d298..e0308f9e7b 100644 --- a/docs/tutorials/gke.md +++ b/docs/tutorials/gke.md @@ -319,7 +319,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/gloo-proxy.md b/docs/tutorials/gloo-proxy.md index be5de4a60a..7a9994eca6 100644 --- a/docs/tutorials/gloo-proxy.md +++ b/docs/tutorials/gloo-proxy.md @@ -22,7 +22,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=gloo-proxy - --gloo-namespace=custom-gloo-system # gloo system namespace. Omit to use the default (gloo-system) @@ -90,7 +90,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=gloo-proxy - --gloo-namespace=custom-gloo-system # gloo system namespace. Omit to use the default (gloo-system) diff --git a/docs/tutorials/godaddy.md b/docs/tutorials/godaddy.md index cd6ba15285..0dddfdf811 100644 --- a/docs/tutorials/godaddy.md +++ b/docs/tutorials/godaddy.md @@ -44,7 +44,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -115,7 +115,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/hostport.md b/docs/tutorials/hostport.md index 2a0d321dc6..dc8052b698 100644 --- a/docs/tutorials/hostport.md +++ b/docs/tutorials/hostport.md @@ -31,7 +31,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --log-level=debug - --source=service @@ -96,7 +96,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --log-level=debug - --source=service diff --git a/docs/tutorials/ibmcloud.md b/docs/tutorials/ibmcloud.md index 6f243bd5ef..b6a164d0f0 100644 --- a/docs/tutorials/ibmcloud.md +++ b/docs/tutorials/ibmcloud.md @@ -69,7 +69,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -142,7 +142,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/infoblox.md b/docs/tutorials/infoblox.md index 3b25aa5230..143067d388 100644 --- a/docs/tutorials/infoblox.md +++ b/docs/tutorials/infoblox.md @@ -69,7 +69,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains. @@ -150,7 +150,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --domain-filter=example.com # (optional) limit to only example.com domains. diff --git a/docs/tutorials/istio.md b/docs/tutorials/istio.md index a63d1d815f..0a519a46bc 100644 --- a/docs/tutorials/istio.md +++ b/docs/tutorials/istio.md @@ -28,7 +28,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress @@ -98,7 +98,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/kong.md b/docs/tutorials/kong.md index fc4fbf20f1..1c5bd6db3e 100644 --- a/docs/tutorials/kong.md +++ b/docs/tutorials/kong.md @@ -22,7 +22,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=kong-tcpingress - --provider=aws @@ -86,7 +86,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=kong-tcpingress - --provider=aws diff --git a/docs/tutorials/linode.md b/docs/tutorials/linode.md index 5884c162e6..101a1be3f7 100644 --- a/docs/tutorials/linode.md +++ b/docs/tutorials/linode.md @@ -41,7 +41,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -105,7 +105,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/nginx-ingress.md b/docs/tutorials/nginx-ingress.md index ce79f24d92..fb663d554a 100644 --- a/docs/tutorials/nginx-ingress.md +++ b/docs/tutorials/nginx-ingress.md @@ -273,7 +273,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --domain-filter=external-dns-test.gcp.zalan.do @@ -568,7 +568,7 @@ spec: - --google-project=zalando-external-dns-test - --registry=txt - --txt-owner-id=my-identifier - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 name: external-dns securityContext: fsGroup: 65534 diff --git a/docs/tutorials/nodes.md b/docs/tutorials/nodes.md index b99a2f9ca3..09507180ef 100644 --- a/docs/tutorials/nodes.md +++ b/docs/tutorials/nodes.md @@ -29,7 +29,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=node # will use nodes as source - --provider=aws @@ -100,7 +100,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=node # will use nodes as source - --provider=aws diff --git a/docs/tutorials/ns1.md b/docs/tutorials/ns1.md index b96ca85a81..faccd6b1c3 100644 --- a/docs/tutorials/ns1.md +++ b/docs/tutorials/ns1.md @@ -61,7 +61,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -125,7 +125,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/openshift.md b/docs/tutorials/openshift.md index e5a995b42c..b8297ee4f7 100644 --- a/docs/tutorials/openshift.md +++ b/docs/tutorials/openshift.md @@ -66,7 +66,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=openshift-route - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones @@ -133,7 +133,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=openshift-route - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones diff --git a/docs/tutorials/oracle.md b/docs/tutorials/oracle.md index d7d385839e..39d804d803 100644 --- a/docs/tutorials/oracle.md +++ b/docs/tutorials/oracle.md @@ -124,7 +124,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/ovh.md b/docs/tutorials/ovh.md index 0f05457f46..5bd5078e55 100644 --- a/docs/tutorials/ovh.md +++ b/docs/tutorials/ovh.md @@ -86,7 +86,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -160,7 +160,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/pdns.md b/docs/tutorials/pdns.md index ff0a9874aa..90efd6f04a 100644 --- a/docs/tutorials/pdns.md +++ b/docs/tutorials/pdns.md @@ -42,7 +42,7 @@ spec: # serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # or ingress or both - --provider=pdns diff --git a/docs/tutorials/pihole.md b/docs/tutorials/pihole.md index dfb3137c9f..29f1403f29 100644 --- a/docs/tutorials/pihole.md +++ b/docs/tutorials/pihole.md @@ -78,7 +78,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 # If authentication is disabled and/or you didn't create # a secret, you can remove this block. envFrom: diff --git a/docs/tutorials/plural.md b/docs/tutorials/plural.md index 956087e934..98aaf2079c 100644 --- a/docs/tutorials/plural.md +++ b/docs/tutorials/plural.md @@ -35,7 +35,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -105,7 +105,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index 66071e13d2..f4c1457337 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -243,7 +243,7 @@ spec: - --txt-owner-id=external-dns - --ingress-class=external-ingress - --aws-zone-type=public - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 name: external-dns-public ``` @@ -281,7 +281,7 @@ spec: - --txt-owner-id=dev.k8s.nexus - --ingress-class=internal-ingress - --aws-zone-type=private - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 name: external-dns-private ``` diff --git a/docs/tutorials/rcodezero.md b/docs/tutorials/rcodezero.md index 7890b8fc91..72ee1b32f2 100644 --- a/docs/tutorials/rcodezero.md +++ b/docs/tutorials/rcodezero.md @@ -53,7 +53,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -120,7 +120,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/rdns.md b/docs/tutorials/rdns.md index 529b1765c2..62653a5088 100644 --- a/docs/tutorials/rdns.md +++ b/docs/tutorials/rdns.md @@ -54,7 +54,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --provider=rdns @@ -123,7 +123,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=ingress - --provider=rdns diff --git a/docs/tutorials/rfc2136.md b/docs/tutorials/rfc2136.md index 63e515826f..144179c083 100644 --- a/docs/tutorials/rfc2136.md +++ b/docs/tutorials/rfc2136.md @@ -218,7 +218,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --registry=txt - --txt-prefix=external-dns- @@ -260,7 +260,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --registry=txt - --txt-prefix=external-dns- diff --git a/docs/tutorials/scaleway.md b/docs/tutorials/scaleway.md index b6aa2d0984..2bd1855309 100644 --- a/docs/tutorials/scaleway.md +++ b/docs/tutorials/scaleway.md @@ -53,7 +53,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -121,7 +121,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. diff --git a/docs/tutorials/security-context.md b/docs/tutorials/security-context.md index 0b5bf39291..107033778b 100644 --- a/docs/tutorials/security-context.md +++ b/docs/tutorials/security-context.md @@ -20,7 +20,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - ... # your arguments here securityContext: diff --git a/docs/tutorials/tencentcloud.md b/docs/tutorials/tencentcloud.md index e5a94311df..ea567f3823 100644 --- a/docs/tutorials/tencentcloud.md +++ b/docs/tutorials/tencentcloud.md @@ -129,7 +129,7 @@ spec: - --policy=sync # set `upsert-only` would prevent ExternalDNS from deleting any records - --tencent-cloud-zone-type=private # only look at private hosted zones. set `public` to use the public dns service. - --tencent-cloud-config-file=/etc/kubernetes/tencent-cloud.json - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 imagePullPolicy: Always name: external-dns resources: {} diff --git a/docs/tutorials/transip.md b/docs/tutorials/transip.md index 83dd6ec509..d2a7aa3f65 100644 --- a/docs/tutorials/transip.md +++ b/docs/tutorials/transip.md @@ -36,7 +36,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains @@ -107,7 +107,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md index af684bebb0..50d98cf6cb 100644 --- a/docs/tutorials/ultradns.md +++ b/docs/tutorials/ultradns.md @@ -44,7 +44,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress # ingress is also possible @@ -116,7 +116,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service - --source=ingress diff --git a/docs/tutorials/vinyldns.md b/docs/tutorials/vinyldns.md index b7166c7776..1005b63c34 100644 --- a/docs/tutorials/vinyldns.md +++ b/docs/tutorials/vinyldns.md @@ -66,7 +66,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --provider=vinyldns - --source=service @@ -137,7 +137,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --provider=vinyldns - --source=service diff --git a/docs/tutorials/vultr.md b/docs/tutorials/vultr.md index 7eef4a580b..0c491c0f64 100644 --- a/docs/tutorials/vultr.md +++ b/docs/tutorials/vultr.md @@ -42,7 +42,7 @@ spec: spec: containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. @@ -106,7 +106,7 @@ spec: serviceAccountName: external-dns containers: - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.13.4 + image: registry.k8s.io/external-dns/external-dns:v0.13.5 args: - --source=service # ingress is also possible - --domain-filter=example.com # (optional) limit to only example.com domains; change to match the zone created above. From 5a7192d8a6e1818f8a213d6f894a2983faebe3f5 Mon Sep 17 00:00:00 2001 From: Antti Viitala <26534322+Antvirf@users.noreply.github.com> Date: Tue, 30 May 2023 16:59:45 +0800 Subject: [PATCH 082/154] docs: update deployment and statefulset apiVersion apps/v1beta2 was deprecated in k8s 1.16 so the examples are no longer working - updated kind to just v1. --- docs/tutorials/hostport.md | 2 +- docs/tutorials/public-private-route53.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/hostport.md b/docs/tutorials/hostport.md index 2a0d321dc6..c2d8ff94d1 100644 --- a/docs/tutorials/hostport.md +++ b/docs/tutorials/hostport.md @@ -114,7 +114,7 @@ spec: First lets deploy a Kafka Stateful set, a simple example(a lot of stuff is missing) with a headless service called `ksvc` ```yaml -apiVersion: apps/v1beta1 +apiVersion: apps/v1 kind: StatefulSet metadata: name: kafka diff --git a/docs/tutorials/public-private-route53.md b/docs/tutorials/public-private-route53.md index 66071e13d2..ef7123a4bb 100644 --- a/docs/tutorials/public-private-route53.md +++ b/docs/tutorials/public-private-route53.md @@ -216,7 +216,7 @@ Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. In ExternalDNS containers args, make sure to specify `aws-zone-type` and `ingress-class`: ```yaml -apiVersion: apps/v1beta2 +apiVersion: apps/v1 kind: Deployment metadata: labels: @@ -254,7 +254,7 @@ Consult [AWS ExternalDNS setup docs](aws.md) for installation guidelines. In ExternalDNS containers args, make sure to specify `aws-zone-type` and `ingress-class`: ```yaml -apiVersion: apps/v1beta2 +apiVersion: apps/v1 kind: Deployment metadata: labels: From 8dc72e5fcdd4f8004c4fce60380d71041b08e323 Mon Sep 17 00:00:00 2001 From: Antti Viitala <26534322+Antvirf@users.noreply.github.com> Date: Tue, 30 May 2023 16:59:52 +0800 Subject: [PATCH 083/154] docs: update rbac.authorization apiVersion --- docs/tutorials/civo.md | 4 ++-- docs/tutorials/gandi.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/civo.md b/docs/tutorials/civo.md index efa5b6fc45..ce20827a61 100644 --- a/docs/tutorials/civo.md +++ b/docs/tutorials/civo.md @@ -59,7 +59,7 @@ kind: ServiceAccount metadata: name: external-dns --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns @@ -74,7 +74,7 @@ rules: resources: ["nodes"] verbs: ["list"] --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-dns-viewer diff --git a/docs/tutorials/gandi.md b/docs/tutorials/gandi.md index 7f4f4036b9..5455ee18b6 100644 --- a/docs/tutorials/gandi.md +++ b/docs/tutorials/gandi.md @@ -56,7 +56,7 @@ kind: ServiceAccount metadata: name: external-dns --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns @@ -71,7 +71,7 @@ rules: resources: ["nodes"] verbs: ["list","watch"] --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-dns-viewer From 40ed5e03b6f517e39593668429bc407027734819 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 1 Jun 2023 21:35:00 -0700 Subject: [PATCH 084/154] Improve registry documentation --- README.md | 11 ++-- docs/proposal/registry.md | 124 -------------------------------------- docs/registry.md | 80 ------------------------ docs/registry/registry.md | 16 +++++ docs/registry/txt.md | 97 +++++++++++++++++++++++++++++ mkdocs.yml | 13 ++-- 6 files changed, 126 insertions(+), 215 deletions(-) delete mode 100644 docs/proposal/registry.md delete mode 100644 docs/registry.md create mode 100644 docs/registry/registry.md create mode 100644 docs/registry/txt.md diff --git a/README.md b/README.md index 88957a8497..ff93823076 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,10 @@ ExternalDNS allows you to keep selected zones (via `--domain-filter`) synchroniz * [Plural](https://www.plural.sh/) * [Pi-hole](https://pi-hole.net/) -From this release, ExternalDNS can become aware of the records it is managing (enabled via `--registry=txt`), therefore ExternalDNS can safely manage non-empty hosted zones. We strongly encourage you to use `v0.5` (or greater) with `--registry=txt` enabled and `--txt-owner-id` set to a unique value that doesn't change for the lifetime of your cluster. You might also want to run ExternalDNS in a dry run mode (`--dry-run` flag) to see the changes to be submitted to your DNS Provider API. +ExternalDNS is, by default, aware of the records it is managing, therefore it can safely manage non-empty hosted zones. We strongly encourage you to set `--txt-owner-id` to a unique value that doesn't change for the lifetime of your cluster. You might also want to run ExternalDNS in a dry run mode (`--dry-run` flag) to see the changes to be submitted to your DNS Provider API. Note that all flags can be replaced with environment variables; for instance, -`--dry-run` could be replaced with `EXTERNAL_DNS_DRY_RUN=1`, or -`--registry txt` could be replaced with `EXTERNAL_DNS_REGISTRY=txt`. +`--dry-run` could be replaced with `EXTERNAL_DNS_DRY_RUN=1`. ## Status of providers @@ -237,17 +236,17 @@ If the service is not of type Loadbalancer you need the --publish-internal-servi Locally run a single sync loop of ExternalDNS. ```console -external-dns --registry txt --txt-owner-id my-cluster-id --provider google --google-project example-project --source service --once --dry-run +external-dns --txt-owner-id my-cluster-id --provider google --google-project example-project --source service --once --dry-run ``` This should output the DNS records it will modify to match the managed zone with the DNS records you desire. It also assumes you are running in the `default` namespace. See the [FAQ](docs/faq.md) for more information regarding namespaces. -Note: TXT records will have `my-cluster-id` value embedded. Those are used to ensure that ExternalDNS is aware of the records it manages. +Note: TXT records will have the `my-cluster-id` value embedded. Those are used to ensure that ExternalDNS is aware of the records it manages. Once you're satisfied with the result, you can run ExternalDNS like you would run it in your cluster: as a control loop, and **not in dry-run** mode: ```console -external-dns --registry txt --txt-owner-id my-cluster-id --provider google --google-project example-project --source service +external-dns --txt-owner-id my-cluster-id --provider google --google-project example-project --source service ``` Check that ExternalDNS has created the desired DNS record for your Service and that it points to its load balancer's IP. Then try to resolve it: diff --git a/docs/proposal/registry.md b/docs/proposal/registry.md deleted file mode 100644 index 84f355dc7f..0000000000 --- a/docs/proposal/registry.md +++ /dev/null @@ -1,124 +0,0 @@ -# Registry -#### [Old name: storage] - -Initial discussion - https://github.com/kubernetes-sigs/external-dns/issues/44 - -## Purpose - -One should not be afraid to use external-dns, because it can delete or overwrite the records preexisting in the DNS provider. - -**Why we need it?** - -DNS provider (AWS Route53, Google DNS, etc.) stores dns records which are created via various means. Integration of External-DNS should be safe and should not delete or overwrite the records which it is not responsible for. Moreover, it should certainly be possible for multiple kubernetes clusters to share the same hosted zone within the dns provider, additionally multiple external-dns instances inside the same cluster should be able to co-exist without messing with the same set of records. - -Registry provides a mechanism to ensure the safe management of DNS records - -This proposal introduces multiple possible implementation with the details depending on the setup. - -## Requirements and assumptions - -1. Pre-existing records should not be modified by external-dns -2. External-dns instance only creates/modifies/deletes records which are created by this instance -3. It should be possible to transfer the ownership to another external-dns instance -4. ~~Any integrated DNS provider should provide at least a single way to implement the registry~~ Noop registry can be used to disable ownership -5. Lifetime of the records should not be limited to lifetime of external-dns -6. External-dns should have its identifier for marking the managed records - **`owner-id`** - -## Types of registry - -The following presents two ways to implement the registry, and we are planning to implement both for compatibility purposes. - -### TXT records - -This implementation idea is borrowed from [Mate](https://github.com/linki/mate/) - -Each record created by external-dns is accompanied by the TXT record, which internally stores the external-dns identifier. For example, if external dns with `owner-id="external-dns-1"` record to be created with dns name `foo.zone.org`, external-dns will create a TXT record with the same dns name `-foo.zone.org` and injected value of `"external-dns-1"`. The transfer of ownership can be done by modifying the value of the TXT record. If no TXT record exists for the record or the value does not match its own `owner-id`, then external-dns will simply ignore it. - -#### Goods -1. Easy to guarantee cross-cluster ownership safety -2. Data lifetime is not limited to cluster or external-dns lifetime -3. Supported by major DNS providers -4. TXT record are created alongside other records in a batch request. Hence **eliminating possibility of having inconsistent ownership information and dns provider state** - -#### Bads -1. TXT record cannot co-exist with CNAME records (this can be solved by creating a TXT record with another domain name, e.g. `foo.org->foo.txt.org`) -2. Introduces complexity to the logic -3. Difficult to do the transfer of ownership -4. Too easy to mess up with manual modifications - -### ConfigMap - -**This implementation cannot be considered 100% error free**, hence use with caution [see **Possible failure scenario** below] - -Store the state in the configmap. ConfigMap is created and managed by each external-dns individually, i.e. external-dns with **`owner-id=external-dns-1`** will create and operate on `extern-dns-1-registry` ConfigMap. ConfigMap will store **all** the records present in the DNS provider as serialized JSON. For example: - -``` -kind: ConfigMap -apiVersion: v1 -metadata: - creationTimestamp: 2016-03-09T19:14:38Z - name: external-dns-1-storage - namespace: same-as-external-dns-1 -data: - records: "[{ - \"dnsname\": \"foo.org\", - \"owner\": \"external-dns-1\", - \"target\": \"loadbalancer1.com\", - \"type\": \"A\" -}, { - \"dnsname\": \"bar.org\", - \"owner\": \"external-dns-2\", - \"target\": \"loadbalancer2.com\", - \"type\": \"A\" -}, { - \"dnsname\": \"unmanaged.org\", - \"owner\": \"\", - \"target\": \"loadbalancer2.com\", - \"type\": \"CNAME\" -}]" - -``` - -ConfigMap will be periodically resynced with the dns provider by fetching the dns records and comparing it with the data currently stored and hence rebuilding the ownership information. - -#### Goods -1. Not difficult to implement and easy to do the ownership transfer -2. ConfigMap is a first class citizen in kubernetes world -3. Does not create dependency/restriction on DNS provider -4. Cannot be easily messed with by other parties - -#### Bads -1. ConfigMap might be out of sync with dns provider state -2. LifeTime is obviously limited to the cluster lifetime -3. Not supported in older kubernetes clusters -4. Bloated ConfigMap - cannot be paginated and will grow very big on DNS provider with thousands of records - -#### Failure scenario - -It is possible that the configmap will go out of sync with the dns provider state. In the implementation flow external-dns will first modify records on dns provider side to subsequently update configmap. And if ExternalDNS will crash in-between two operation created records will be left unmanaged and not viable for update/deletion by External DNS. - -## Component integration - -Components: -* Source - all endpoints ( collection of ingress, service[type=LoadBalancer] etc.) -* [Plan](https://github.com/kubernetes-sigs/external-dns/issues/13) - object responsible for the create of change lists in external-dns -* Provider - interface to access the DNS provider API - -Registry will serve as wrapper around `Provider` providing additional information regarding endpoint ownership. Ownership will further taken into account by `Plan` to filter out records to include only records managed by current ExternalDNS instance (having same `owner-id` value) - -A single loop iteration of external-dns operation: - -1. Get all endpoints ( collection ingress, service[type=LoadBalancer] etc.) into collection of `endpoints` -2. Get registry `Records()` (makes the call to DNSProvider and also build ownership information) -3. Pass `Records` (including ownership information) and list of endpoints to `Plan` to do the calculation -4. Call registry `ApplyChanges()` method (which subsequently calls DNS Provider Apply method to update records) -5. If ConfigMap implementation of Registry is used, then ConfigMap needs to be updated separately - -~~In case of configmap, Registry gets updated all the time via `Poll`. `Plan` does not call DNS provider directly. Good value of the `Poll` is to have simple rate limiting mechanism on DNS provider.~~ - -#### Notes: - -1. DNS Provider should use batch operations -2. DNS Provider should be called with CREATE operation (not UPSERT!) when the record does not yet exist! - - diff --git a/docs/registry.md b/docs/registry.md deleted file mode 100644 index 3ff20b93a7..0000000000 --- a/docs/registry.md +++ /dev/null @@ -1,80 +0,0 @@ -### TXT Registry migration to a new format ### - -In order to support more record types and be able to track ownership without TXT record name clash, a new TXT record is introduced. -It contains record type it manages, e.g.: -* A record foo.example.com will be tracked with classic foo.example.com TXT record -* At the same time a new TXT record will be created a-foo.example.com - -Prefix and suffix are extended with %{record_type} template where the user can control how prefixed/suffixed records should look like. - -In order to maintain compatibility, both records will be maintained for some time, in order to have downgrade possibility. -The controller will try to create the "new format" TXT records if they are not present to ease the migration from the versions < 0.12.0. - -Later on, the old format will be dropped and only the new format will be kept (-). - -Cleanup will be done by controller itself. - -### Encryption of TXT Records -TXT records may contain sensitive information, such as the internal ingress name or namespace, which attackers could exploit to gather information about your infrastructure. -By encrypting TXT records, you can protect this information from unauthorized access. It is strongly recommended to encrypt all TXT records to prevent potential security breaches. - -To enable encryption of TXT records, you can use the following parameters: -- `--txt-encrypt-enabled=true` -- `--txt-encrypt-aes-key=32bytesKey` (used for AES-256-GCM encryption and should be exactly 32 bytes) - -Note that the key used for encryption should be a secure key and properly managed to ensure the security of your TXT records. - -### Generating TXT encryption AES key -Python -```python -python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())' -``` - -Bash -```shell -dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo -``` - -OpenSSL -```shell -openssl rand -base64 32 | tr -- '+/' '-_' -``` - -PowerShell -```powershell -# Add System.Web assembly to session, just in case -Add-Type -AssemblyName System.Web -[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([System.Web.Security.Membership]::GeneratePassword(32,4))).Replace("+","-").Replace("/","_") -``` - -Terraform -```hcl -resource "random_password" "txt_key" { - length = 32 - override_special = "-_" -} -``` - -### Manually Encrypt/Decrypt TXT Records - -In some cases, you may need to edit labels generated by External-DNS, and in such cases, you can use simple Golang code to do that. - -```go -package main - -import ( - "fmt" - "sigs.k8s.io/external-dns/endpoint" -) - -func main() { - key := []byte("testtesttesttesttesttesttesttest") - encrypted, _ := endpoint.EncryptText( - "heritage=external-dns,external-dns/owner=example,external-dns/resource=ingress/default/example", - key, - nil, - ) - decrypted, _, _ := endpoint.DecryptText(encrypted, key) - fmt.Println(decrypted) -} -``` diff --git a/docs/registry/registry.md b/docs/registry/registry.md new file mode 100644 index 0000000000..6d4466b3ec --- /dev/null +++ b/docs/registry/registry.md @@ -0,0 +1,16 @@ +# Registries + +A registry persists metadata pertaining to DNS records. + +The most important metadata is the owning external-dns deployment. +This is specified using the `--txt-owner-id` flag, specifying a value unique to the +deployment of external-dns and which doesn't change for the lifetime of the deployment. +Deployments in different clusters but sharing a DNS zone need to use different owner IDs. + +The registry implementation is specified using the `--registry` flag. + +## Supported registries + +* [txt](txt.md) (default) - Stores in TXT records in the same provider +* noop - Passes metadata directly to the provider. For most providers, this means the metadata is not persisted. +* aws-sd - Stores metadata in AWS Service Discovery. Only usable with the `aws-sd` provider. diff --git a/docs/registry/txt.md b/docs/registry/txt.md new file mode 100644 index 0000000000..c6ea26bfbd --- /dev/null +++ b/docs/registry/txt.md @@ -0,0 +1,97 @@ +# The TXT registry + +The TXT registry is the default registry. +It stores DNS record metadata in TXT records, using the same provider. + +## Prefixes and Suffixes + +In order to avoid having the registry TXT records collide with +TXT or CNAME records created from sources, you can configure a fixed prefix or suffix +to be added to the first component of the domain of all registry TXT records. + +The prefix or suffix may not be changed after initial deployment, +lest the registry records be orphaned and the metadata be lost. + +The prefix or suffix may contain the substring `%{record_type}`, which is replaced with +the record type of the DNS record for which it is storing metadata. + +The prefix is specified using the `--txt-prefix` flag and the suffix is specified using +the `--txt-suffix` flag. The two flags are mutually exclusive. + +## Wildcard Replacement + +The `--txt-wildcard-replacement` flag specifies a string to use to replace the "*" in +registry TXT records for wildcard domains. Without using this, registry TXT records for +wildcard domains will have invalid domain syntax and be rejected by most providers. + +## Encryption + +Registry TXT records may contain information, such as the internal ingress name or namespace, considered sensitive, , which attackers could exploit to gather information about your infrastructure. +By encrypting TXT records, you can protect this information from unauthorized access. + +Encryption is enabled by using the `--txt-encrypt-enabled` flag. The 32-byte AES-256-GCM encryption +key must be specified in URL-safe base64 form, using the `--txt-encrypt-aes-key` flag. + +Note that the key used for encryption should be a secure key and properly managed to ensure the security of your TXT records. + +### Generating the TXT Encryption Key +Python +```python +python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())' +``` + +Bash +```shell +dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo +``` + +OpenSSL +```shell +openssl rand -base64 32 | tr -- '+/' '-_' +``` + +PowerShell +```powershell +# Add System.Web assembly to session, just in case +Add-Type -AssemblyName System.Web +[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([System.Web.Security.Membership]::GeneratePassword(32,4))).Replace("+","-").Replace("/","_") +``` + +Terraform +```hcl +resource "random_password" "txt_key" { + length = 32 + override_special = "-_" +} +``` + +### Manually Encrypting/Decrypting TXT Records + +In some cases you might need to edit registry TXT records. The following example Go code encrypts and decrypts such records. + +```go +package main + +import ( + "fmt" + "sigs.k8s.io/external-dns/endpoint" +) + +func main() { + key := []byte("testtesttesttesttesttesttesttest") + encrypted, _ := endpoint.EncryptText( + "heritage=external-dns,external-dns/owner=example,external-dns/resource=ingress/default/example", + key, + nil, + ) + decrypted, _, _ := endpoint.DecryptText(encrypted, key) + fmt.Println(decrypted) +} +``` + +## Caching + +The TXT registry can optionally cache DNS records read from the provider. This can mitigate +rate limits imposed by the provider. + +Caching is enabled by specifying a cache duration with the `--txt-cache-interval` flag. diff --git a/mkdocs.yml b/mkdocs.yml index c1b9ed6237..f20cf1f907 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,7 +6,15 @@ repo_url: https://github.com/kubernetes-sigs/external-dns/ nav: - index.md + - About: + - FAQ: faq.md + - Out of Incubator: 20190708-external-dns-incubator.md + - Code of Conduct: code-of-conduct.md + - License: LICENSE.md - Tutorials: tutorials/ + - Registries: + - About: registry/registry.md + - TXT: registry/txt.md - Advanced Topics: - Initial Design: initial-design.md - TTL: ttl.md @@ -14,11 +22,6 @@ nav: - Kubernetes Contributions: CONTRIBUTING.md - Release: release.md - contributing/* - - About: - - FAQ: faq.md - - Out of Incubator: 20190708-external-dns-incubator.md - - Code of Conduct: code-of-conduct.md - - License: LICENSE.md theme: name: material From 8d04d23101d63e21ccb076cb66f998386eb27a52 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 1 Jun 2023 21:40:26 -0700 Subject: [PATCH 085/154] Remove roadmap section from README.md --- README.md | 65 ------------------------------------------------------- 1 file changed, 65 deletions(-) diff --git a/README.md b/README.md index 88957a8497..495d94f13f 100644 --- a/README.md +++ b/README.md @@ -271,71 +271,6 @@ If using a txt registry and attempting to use a CNAME the `--txt-prefix` must be If `externalIPs` list is defined for a `LoadBalancer` service, this list will be used instead of an assigned load balancer IP to create a DNS record. It's useful when you run bare metal Kubernetes clusters behind NAT or in a similar setup, where a load balancer IP differs from a public IP (e.g. with [MetalLB](https://metallb.universe.tf)). -# Roadmap - -ExternalDNS was built with extensibility in mind. Adding and experimenting with new DNS providers and sources of desired DNS records should be as easy as possible. It should also be possible to modify how ExternalDNS behaves—e.g. whether it should add records but never delete them. - -Here's a rough outline on what is to come (subject to change): - -### v0.1 - -- [x] Support for Google CloudDNS -- [x] Support for Kubernetes Services - -### v0.2 - -- [x] Support for AWS Route 53 -- [x] Support for Kubernetes Ingresses - -### v0.3 - -- [x] Support for AWS Route 53 via ALIAS -- [x] Support for multiple zones -- [x] Ownership System - -### v0.4 - -- [x] Support for AzureDNS -- [x] Support for CloudFlare -- [x] Support for DigitalOcean -- [x] Multiple DNS names per Service - -### v0.5 - -- [x] Support for creating DNS records to multiple targets (for Google and AWS) -- [x] Support for OpenStack Designate -- [x] Support for PowerDNS -- [x] Support for Linode -- [x] Support for RcodeZero -- [x] Support for NS1 -- [x] Support for TransIP -- [x] Support for Azure Private DNS - -### v0.6 - -- [ ] Ability to replace kOps' [DNS Controller](https://github.com/kubernetes/kops/tree/HEAD/dns-controller) (This could also directly become `v1.0`) -- [x] Support for OVH - -### v1.0 - -- [ ] Ability to replace kOps' [DNS Controller](https://github.com/kubernetes/kops/tree/HEAD/dns-controller) - - [x] Add support for pod source - - [x] Add support for DNS Controller annotations for pod and service sources - - [ ] Add support for kOps gossip provider -- [x] Ability to replace Zalando's [Mate](https://github.com/linki/mate) -- [x] Ability to replace Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes) - -### Yet to be defined - -* Support for CoreDNS -* Support for record weights -* Support for different behavioral policies -* Support for Services with `type=NodePort` -* Support for CRDs -* Support for more advanced DNS record configurations - -Have a look at [the milestones](https://github.com/kubernetes-sigs/external-dns/milestones) to get an idea of where we currently stand. - ## Contributing Are you interested in contributing to external-dns? We, the maintainers and community, would love your From 23326bd4bf1ee5e107b3cd7f587deb417bca9de2 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Fri, 2 Jun 2023 12:47:34 +0200 Subject: [PATCH 086/154] Added traefik-proxy to source docs string Signed-off-by: Thomas Kosiewski --- pkg/apis/externaldns/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 253638e3a8..82f721a143 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -414,7 +414,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(source.DefaultRoutegroupVersion).StringVar(&cfg.SkipperRouteGroupVersion) // Flags related to processing source - app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "traefik-proxy") + app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, traefik-proxy)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "traefik-proxy") app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName) app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) From 7efecc711ff796d24ba679028f437f67fb8a438d Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Mon, 5 Jun 2023 12:49:20 -0700 Subject: [PATCH 087/154] Simplify TargetFilterInterface --- endpoint/target_filter.go | 14 --------- endpoint/target_filter_test.go | 57 ---------------------------------- 2 files changed, 71 deletions(-) diff --git a/endpoint/target_filter.go b/endpoint/target_filter.go index 1d1b90c880..e4e69957fa 100644 --- a/endpoint/target_filter.go +++ b/endpoint/target_filter.go @@ -26,7 +26,6 @@ import ( // TargetFilterInterface defines the interface to select matching targets for a specific provider or runtime type TargetFilterInterface interface { Match(target string) bool - IsConfigured() bool } // TargetNetFilter holds a lists of valid target names @@ -61,11 +60,6 @@ func NewTargetNetFilterWithExclusions(targetFilterNets []string, excludeNets []s return TargetNetFilter{FilterNets: prepareTargetFilters(targetFilterNets), excludeNets: prepareTargetFilters(excludeNets)} } -// NewTargetNetFilter returns a new TargetNetFilter given a comma separated list of targets -func NewTargetNetFilter(targetFilterNets []string) TargetNetFilter { - return TargetNetFilter{FilterNets: prepareTargetFilters(targetFilterNets)} -} - // Match checks whether a target can be found in the TargetNetFilter. func (tf TargetNetFilter) Match(target string) bool { return matchTargetNetFilter(tf.FilterNets, target, true) && !matchTargetNetFilter(tf.excludeNets, target, false) @@ -89,11 +83,3 @@ func matchTargetNetFilter(filters []*net.IPNet, target string, emptyval bool) bo return false } - -// IsConfigured returns true if TargetFilter is configured, false otherwise -func (tf TargetNetFilter) IsConfigured() bool { - if len(tf.FilterNets) == 1 { - return tf.FilterNets[0].Network() != "" - } - return len(tf.FilterNets) > 0 -} diff --git a/endpoint/target_filter_test.go b/endpoint/target_filter_test.go index 4d7380426e..57690f7c1d 100644 --- a/endpoint/target_filter_test.go +++ b/endpoint/target_filter_test.go @@ -68,19 +68,6 @@ var targetFilterTests = []targetFilterTest{ }, } -func TestTargetFilterMatch(t *testing.T) { - for i, tt := range targetFilterTests { - if len(tt.exclusions) > 0 { - t.Logf("NewTargetFilter() doesn't support exclusions - skipping test %+v", tt) - continue - } - targetFilter := NewTargetNetFilter(tt.targetFilter) - for _, target := range tt.targets { - assert.Equal(t, tt.expected, targetFilter.Match(target), "should not fail: %v in test-case #%v", target, i) - } - } -} - func TestTargetFilterWithExclusions(t *testing.T) { for i, tt := range targetFilterTests { if len(tt.exclusions) == 0 { @@ -107,47 +94,3 @@ func TestMatchTargetFilterReturnsProperEmptyVal(t *testing.T) { assert.Equal(t, true, matchFilter(emptyFilters, "sometarget.com", true)) assert.Equal(t, false, matchFilter(emptyFilters, "sometarget.com", false)) } - -func TestTargetFilterIsConfigured(t *testing.T) { - for _, tt := range []struct { - filters []string - exclude []string - expected bool - }{ - { - []string{""}, - []string{""}, - false, - }, - { - []string{" "}, - []string{" "}, - false, - }, - { - []string{"", ""}, - []string{""}, - false, - }, - { - []string{"10/8"}, - []string{" "}, - false, - }, - { - []string{"10.0.0.0/8"}, - []string{" "}, - true, - }, - { - []string{" 10.0.0.0/8 "}, - []string{" ignored "}, - true, - }, - } { - t.Run("test IsConfigured", func(t *testing.T) { - tf := NewTargetNetFilterWithExclusions(tt.filters, tt.exclude) - assert.Equal(t, tt.expected, tf.IsConfigured()) - }) - } -} From d1fb3423c463b60d0d55d5131852d802f472f996 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Mon, 5 Jun 2023 12:49:20 -0700 Subject: [PATCH 088/154] Simplify DomainFilterInterface --- endpoint/domain_filter.go | 21 +-------------------- provider/akamai/akamai.go | 2 +- provider/pihole/client.go | 4 ++-- provider/tencentcloud/privatedns.go | 2 +- provider/zone_id_filter.go | 3 +++ 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/endpoint/domain_filter.go b/endpoint/domain_filter.go index 1fe36aee05..8ddde179b6 100644 --- a/endpoint/domain_filter.go +++ b/endpoint/domain_filter.go @@ -24,41 +24,22 @@ import ( // DomainFilterInterface defines the interface to select matching domains for a specific provider or runtime type DomainFilterInterface interface { Match(domain string) bool - IsConfigured() bool } type MatchAllDomainFilters []DomainFilterInterface func (f MatchAllDomainFilters) Match(domain string) bool { - if !f.IsConfigured() { - return true - } for _, filter := range f { if filter == nil { continue } - if filter.IsConfigured() && !filter.Match(domain) { + if !filter.Match(domain) { return false } } return true } -func (f MatchAllDomainFilters) IsConfigured() bool { - if f == nil { - return false - } - for _, filter := range f { - if filter == nil { - continue - } - if filter.IsConfigured() { - return true - } - } - return len(f) > 0 -} - // DomainFilter holds a lists of valid domain names type DomainFilter struct { // Filters define what domains to match diff --git a/provider/akamai/akamai.go b/provider/akamai/akamai.go index 6547edce08..f59bd384f0 100644 --- a/provider/akamai/akamai.go +++ b/provider/akamai/akamai.go @@ -199,7 +199,7 @@ func (p AkamaiProvider) fetchZones() (akamaiZones, error) { } for _, zone := range resp.Zones { - if p.domainFilter.Match(zone.Zone) || !p.domainFilter.IsConfigured() { + if p.domainFilter.Match(zone.Zone) { filteredZones.Zones = append(filteredZones.Zones, akamaiZone{ContractID: zone.ContractId, Zone: zone.Zone}) log.Debugf("Fetched zone: '%s' (ZoneID: %s)", zone.Zone, zone.ContractId) } diff --git a/provider/pihole/client.go b/provider/pihole/client.go index df6fb4c576..4ca6552587 100644 --- a/provider/pihole/client.go +++ b/provider/pihole/client.go @@ -148,7 +148,7 @@ func (p *piholeClient) listRecords(ctx context.Context, rtype string) ([]*endpoi for _, rec := range data { name := rec[0] target := rec[1] - if p.cfg.DomainFilter.IsConfigured() && !p.cfg.DomainFilter.Match(name) { + if !p.cfg.DomainFilter.Match(name) { log.Debugf("Skipping %s that does not match domain filter", name) continue } @@ -195,7 +195,7 @@ type actionResponse struct { } func (p *piholeClient) apply(ctx context.Context, action string, ep *endpoint.Endpoint) error { - if p.cfg.DomainFilter.IsConfigured() && !p.cfg.DomainFilter.Match(ep.DNSName) { + if !p.cfg.DomainFilter.Match(ep.DNSName) { log.Debugf("Skipping %s %s that does not match domain filter", action, ep.DNSName) return nil } diff --git a/provider/tencentcloud/privatedns.go b/provider/tencentcloud/privatedns.go index ad29418331..7bfc9d326f 100644 --- a/provider/tencentcloud/privatedns.go +++ b/provider/tencentcloud/privatedns.go @@ -119,7 +119,7 @@ func (p *TencentCloudProvider) getPrivateZones() ([]*privatedns.PrivateZone, err privateZonesFilter := make([]*privatedns.PrivateZone, 0) for _, privateZone := range privateZones { - if p.domainFilter.IsConfigured() && !p.domainFilter.Match(*privateZone.Domain) { + if !p.domainFilter.Match(*privateZone.Domain) { continue } privateZonesFilter = append(privateZonesFilter, privateZone) diff --git a/provider/zone_id_filter.go b/provider/zone_id_filter.go index 50a016b2d8..7a7b10621b 100644 --- a/provider/zone_id_filter.go +++ b/provider/zone_id_filter.go @@ -34,6 +34,9 @@ func (f ZoneIDFilter) Match(zoneID string) bool { if len(f.ZoneIDs) == 0 { return true } + if len(f.ZoneIDs) == 1 && f.ZoneIDs[0] == "" { + return true + } for _, id := range f.ZoneIDs { if strings.HasSuffix(zoneID, id) { From f0ac6558380e5ea46d088cfee69ed43f2036a5fd Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Tue, 6 Jun 2023 18:51:59 +0200 Subject: [PATCH 089/154] Style changes & fixes Signed-off-by: Thomas Kosiewski --- source/traefik_proxy.go | 76 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index 9e4b09b392..ffdd791f27 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -163,7 +163,7 @@ func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { for _, ingressRouteObj := range irs { unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) if !ok { - return nil, errors.New("could not convert") + return nil, errors.New("could not convert IngressRoute object to unstructured") } ingressRoute := &IngressRoute{} @@ -174,7 +174,7 @@ func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) { ingressRoutes = append(ingressRoutes, ingressRoute) } - ingressRoutes, err = ts.filterByAnnotationsIngressRoute(ingressRoutes) + ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes) if err != nil { return nil, errors.Wrap(err, "failed to filter IngressRoute") } @@ -213,34 +213,34 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error return nil, err } - var ingressRoutes []*IngressRouteTCP - for _, ingressRouteObj := range irs { - unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + var ingressRouteTCPs []*IngressRouteTCP + for _, ingressRouteTCPObj := range irs { + unstructuredHost, ok := ingressRouteTCPObj.(*unstructured.Unstructured) if !ok { - return nil, errors.New("could not convert") + return nil, errors.New("could not convert IngressRouteTCP object to unstructured") } - ingressRoute := &IngressRouteTCP{} - err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + ingressRouteTCP := &IngressRouteTCP{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRouteTCP, nil) if err != nil { return nil, err } - ingressRoutes = append(ingressRoutes, ingressRoute) + ingressRouteTCPs = append(ingressRouteTCPs, ingressRouteTCP) } - ingressRoutes, err = ts.filterByAnnotationsIngressRouteTCP(ingressRoutes) + ingressRouteTCPs, err = ts.filterIngressRouteTcpByAnnotations(ingressRouteTCPs) if err != nil { - return nil, errors.Wrap(err, "failed to filter IngressRoute") + return nil, errors.Wrap(err, "failed to filter IngressRouteTCP") } - for _, ingressRoute := range ingressRoutes { + for _, ingressRouteTCP := range ingressRouteTCPs { var targets endpoint.Targets - targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteTCP.Annotations)...) - fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name) - ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRoute, targets) + ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets) if err != nil { return nil, err } @@ -249,9 +249,9 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error continue } - log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) - ts.setResourceLabelIngressRouteTCP(ingressRoute, ingressEndpoints) - ts.setDualstackLabelIngressRouteTCP(ingressRoute, ingressEndpoints) + log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints) + ts.setDualstackLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints) endpoints = append(endpoints, ingressEndpoints...) } @@ -267,11 +267,11 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error return nil, err } - var ingressRoutes []*IngressRouteUDP - for _, ingressRouteObj := range irs { - unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + var ingressRouteUDPs []*IngressRouteUDP + for _, ingressRouteUDPObj := range irs { + unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured) if !ok { - return nil, errors.New("could not convert") + return nil, errors.New("could not convert IngressRouteUDP object to unstructured") } ingressRoute := &IngressRouteUDP{} @@ -279,22 +279,22 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error if err != nil { return nil, err } - ingressRoutes = append(ingressRoutes, ingressRoute) + ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute) } - ingressRoutes, err = ts.filterByAnnotationsIngressRouteUDP(ingressRoutes) + ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs) if err != nil { - return nil, errors.Wrap(err, "failed to filter IngressRoute") + return nil, errors.Wrap(err, "failed to filter IngressRouteUDP") } - for _, ingressRoute := range ingressRoutes { + for _, ingressRouteUDP := range ingressRouteUDPs { var targets endpoint.Targets - targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...) - fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name) - ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRoute, targets) + ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets) if err != nil { return nil, err } @@ -303,17 +303,17 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error continue } - log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) - ts.setResourceLabelIngressRouteUDP(ingressRoute, ingressEndpoints) - ts.setDualstackLabelIngressRouteUDP(ingressRoute, ingressEndpoints) + log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints) + ts.setDualstackLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints) endpoints = append(endpoints, ingressEndpoints...) } return endpoints, nil } -// filterByAnnotations filters a list of IngressRoute by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) { +// filterIngressRouteByAnnotation filters a list of IngressRoute by a given annotation selector. +func (ts *traefikSource) filterIngressRouteByAnnotation(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err @@ -343,8 +343,8 @@ func (ts *traefikSource) filterByAnnotationsIngressRoute(ingressRoutes []*Ingres return filteredList, nil } -// filterByAnnotations filters a list of IngressRouteTCP by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*IngressRouteTCP) ([]*IngressRouteTCP, error) { +// filterIngressRouteTcpByAnnotations filters a list of IngressRouteTCP by a given annotation selector. +func (ts *traefikSource) filterIngressRouteTcpByAnnotations(ingressRoutes []*IngressRouteTCP) ([]*IngressRouteTCP, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err @@ -374,8 +374,8 @@ func (ts *traefikSource) filterByAnnotationsIngressRouteTCP(ingressRoutes []*Ing return filteredList, nil } -// filterByAnnotations filters a list of IngressRoute by a given annotation selector. -func (ts *traefikSource) filterByAnnotationsIngressRouteUDP(ingressRoutes []*IngressRouteUDP) ([]*IngressRouteUDP, error) { +// filterIngressRouteUdpByAnnotations filters a list of IngressRoute by a given annotation selector. +func (ts *traefikSource) filterIngressRouteUdpByAnnotations(ingressRoutes []*IngressRouteUDP) ([]*IngressRouteUDP, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) if err != nil { return nil, err From bbe233d55cd750e0d278b340b7a13837c7030c4e Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Tue, 6 Jun 2023 19:36:25 -0700 Subject: [PATCH 090/154] Add johngmyers to reviewers --- OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS b/OWNERS index dfd80b17e9..4ca6d6bfa5 100644 --- a/OWNERS +++ b/OWNERS @@ -8,6 +8,7 @@ approvers: - szuecs reviewers: + - johngmyers - njuettner - raffo - seanmalloy From 2241953e1873d42d66c74c1c442f7258a271ab43 Mon Sep 17 00:00:00 2001 From: Gabriel Martinez <19713226+GMartinez-Sisti@users.noreply.github.com> Date: Wed, 7 Jun 2023 20:42:13 +0100 Subject: [PATCH 091/154] feat(chart): updated chart to ExternalDNS v0.13.5 (#3661) * feat(chart): updated chart to ExternalDNS v0.13.5 * update PR * remove reverted change from changelog --- charts/external-dns/CHANGELOG.md | 9 ++++++++- charts/external-dns/Chart.yaml | 16 ++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/charts/external-dns/CHANGELOG.md b/charts/external-dns/CHANGELOG.md index 5c2d88be39..83f322a984 100644 --- a/charts/external-dns/CHANGELOG.md +++ b/charts/external-dns/CHANGELOG.md @@ -11,7 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### All Changes -## [v1.12.2] - UNRELEASED +## [v1.13.0] - 2023-03-30 + +### All Changes + +- Updated _ExternalDNS_ version to [v0.13.5](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.13.5). ([#3661](https://github.com/kubernetes-sigs/external-dns/pull/3661)) [@GMartinez-Sisti](https://github.com/GMartinez-Sisti) +- Adding missing gateway-httproute cluster role permission. ([#3541](https://github.com/kubernetes-sigs/external-dns/pull/3541)) [@nicon89](https://github.com/nicon89) + +## [v1.12.2] - 2023-03-30 ### All Changes diff --git a/charts/external-dns/Chart.yaml b/charts/external-dns/Chart.yaml index 0e4e2cd9bb..8498852a7e 100644 --- a/charts/external-dns/Chart.yaml +++ b/charts/external-dns/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: external-dns description: ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers. type: application -version: 1.12.2 -appVersion: 0.13.4 +version: 1.13.0 +appVersion: 0.13.5 keywords: - kubernetes - externaldns @@ -20,15 +20,7 @@ maintainers: email: steve.hipwell@gmail.com annotations: artifacthub.io/changes: | - - kind: added - description: "Added support for ServiceMonitor relabelling." - kind: changed - description: "Updated chart icon path." - - kind: added - description: "Added RBAC for Gateway-API resources to ClusterRole." - - kind: added - description: "Added RBAC for F5 VirtualServer to ClusterRole." - - kind: added - description: "Added support for running ExternalDNS with namespaced scope." + description: "Updated _ExternalDNS_ version to [v0.13.5](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.13.5)." - kind: changed - description: "Updated _ExternalDNS_ version to [v0.13.4](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.13.4)." + description: "Adding missing gateway-httproute cluster role permission." From 8863810d64036430fdec24a2bfbaa9d92dc50067 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 04:06:15 +0000 Subject: [PATCH 092/154] build(deps): bump github.com/IBM-Cloud/ibm-cloud-cli-sdk Bumps [github.com/IBM-Cloud/ibm-cloud-cli-sdk](https://github.com/IBM-Cloud/ibm-cloud-cli-sdk) from 1.0.0 to 1.1.0. - [Release notes](https://github.com/IBM-Cloud/ibm-cloud-cli-sdk/releases) - [Commits](https://github.com/IBM-Cloud/ibm-cloud-cli-sdk/compare/v1.0.0...v1.1.0) --- updated-dependencies: - dependency-name: github.com/IBM-Cloud/ibm-cloud-cli-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d7b624ae47..16af9aad9b 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/Azure/go-autorest/autorest/adal v0.9.21 github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 - github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.0.0 + github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 github.com/IBM/go-sdk-core/v5 v5.8.0 github.com/IBM/networking-go-sdk v0.36.0 github.com/StackExchange/dnscontrol/v3 v3.27.1 diff --git a/go.sum b/go.sum index 69d3d71f0e..cb1d8eea52 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/F5Networks/f5-ipam-controller v0.1.6-0.20211217134627-c2be8b459270/go.mod h1:XBOjYUVRKG8q8atIpNmil/XF6RAGVekqfbeNQludcV4= github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 h1:/ZCtF9JC9VyTN2bdwtHnlpCoJOWxZON5Sh7QDtFlB1E= github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1/go.mod h1:vdlVHq8oUD8W8yUr53RSZ9hKkOcboFcgvhS6nMKH+qc= -github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.0.0 h1:2gzVSELk4I4ncZNrsaKI6fvZ3to60iYnig+lTFcGCEM= -github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.0.0/go.mod h1:P9YNyJaJazc49fLNFG4uQ61VZVptykWqNU2vWLWcxu0= +github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= +github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/networking-go-sdk v0.36.0 h1:ADntTsRM8DMZOxS9TYGTAL6i0zw9V2L7OeLFd9Czntk= From f4756f849814d4cd23f0a35d2261bfd41a970e03 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 8 Jun 2023 15:51:25 -0700 Subject: [PATCH 093/154] Remove unnecessary Route53 code --- provider/aws/aws.go | 31 -------------------------- provider/aws/aws_test.go | 47 ++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 45 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index e8fcd06b1f..45792e04ad 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -458,37 +458,6 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos return endpoints, nil } -// CreateRecords creates a given set of DNS records in the given hosted zone. -func (p *AWSProvider) CreateRecords(ctx context.Context, endpoints []*endpoint.Endpoint) error { - return p.doRecords(ctx, route53.ChangeActionCreate, endpoints) -} - -// DeleteRecords deletes a given set of DNS records in a given zone. -func (p *AWSProvider) DeleteRecords(ctx context.Context, endpoints []*endpoint.Endpoint) error { - return p.doRecords(ctx, route53.ChangeActionDelete, endpoints) -} - -func (p *AWSProvider) doRecords(ctx context.Context, action string, endpoints []*endpoint.Endpoint) error { - zones, err := p.Zones(ctx) - if err != nil { - return errors.Wrapf(err, "failed to list zones, aborting %s doRecords action", action) - } - - p.AdjustEndpoints(endpoints) - - return p.submitChanges(ctx, p.newChanges(action, endpoints), zones) -} - -// UpdateRecords updates a given set of old records to a new set of records in a given hosted zone. -func (p *AWSProvider) UpdateRecords(ctx context.Context, updates, current []*endpoint.Endpoint) error { - zones, err := p.Zones(ctx) - if err != nil { - return errors.Wrapf(err, "failed to list zones, aborting UpdateRecords") - } - - return p.submitChanges(ctx, p.createUpdateChanges(updates, current), zones) -} - // Identify if old and new endpoints require DELETE/CREATE instead of UPDATE. func (p *AWSProvider) requiresDeleteCreate(old *endpoint.Endpoint, new *endpoint.Endpoint) bool { // a change of record type diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 7382b54f35..3a3fbf2581 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -550,13 +550,15 @@ func TestAWSCreateRecords(t *testing.T) { endpoint.NewEndpoint("create-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpointWithTTL("create-test-custom-ttl.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, customTTL, "172.17.0.1"), endpoint.NewEndpoint("create-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com"), - endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"), + endpoint.NewEndpoint("create-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpoint("create-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpoint("create-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8", "8.8.4.4"), endpoint.NewEndpoint("create-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.example.com", "20 mailhost2.example.com"), } - require.NoError(t, provider.CreateRecords(context.Background(), records)) + require.NoError(t, provider.ApplyChanges(context.Background(), &plan.Changes{ + Create: records, + })) validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ { @@ -675,7 +677,10 @@ func TestAWSUpdateRecords(t *testing.T) { endpoint.NewEndpoint("update-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), } - require.NoError(t, provider.UpdateRecords(context.Background(), updatedRecords, currentRecords)) + require.NoError(t, provider.ApplyChanges(context.Background(), &plan.Changes{ + UpdateOld: currentRecords, + UpdateNew: updatedRecords, + })) validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{ { @@ -780,15 +785,17 @@ func TestAWSDeleteRecords(t *testing.T) { }, }) - require.NoError(t, provider.DeleteRecords(context.Background(), []*endpoint.Endpoint{ - endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), - endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), - endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"), - endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), - endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), - endpoint.NewEndpoint("delete-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "delete-test.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificTargetHostedZone, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), - endpoint.NewEndpointWithTTL("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), - endpoint.NewEndpoint("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), + require.NoError(t, provider.ApplyChanges(context.Background(), &plan.Changes{ + Delete: []*endpoint.Endpoint{ + endpoint.NewEndpointWithTTL("delete-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), + endpoint.NewEndpointWithTTL("delete-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), + endpoint.NewEndpointWithTTL("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "baz.elb.amazonaws.com"), + endpoint.NewEndpoint("delete-test-cname.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false").WithProviderSpecific(providerSpecificAlias, "true"), + endpoint.NewEndpoint("delete-test-cname-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true"), + endpoint.NewEndpoint("delete-test-cname-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "delete-test.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificTargetHostedZone, "/hostedzone/zone-2.ext-dns-test-2.teapot.zalan.do."), + endpoint.NewEndpointWithTTL("delete-test-multiple.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8", "8.8.4.4"), + endpoint.NewEndpoint("delete-test-mx.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, "10 mailhost1.foo.elb.amazonaws.com", "20 mailhost2.foo.elb.amazonaws.com"), + }, })) validateRecords(t, listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do."), []*route53.ResourceRecordSet{}) @@ -1638,7 +1645,9 @@ func TestAWSCreateRecordsWithCNAME(t *testing.T) { {DNSName: "create-test.zone-1.ext-dns-test-2.teapot.zalan.do", Targets: endpoint.Targets{"foo.example.org"}, RecordType: endpoint.RecordTypeCNAME}, } - require.NoError(t, provider.CreateRecords(context.Background(), records)) + require.NoError(t, provider.ApplyChanges(context.Background(), &plan.Changes{ + Create: records, + })) recordSets := listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do.") @@ -1671,6 +1680,10 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) { Targets: endpoint.Targets{"foo.eu-central-1.elb.amazonaws.com"}, RecordType: endpoint.RecordTypeCNAME, ProviderSpecific: endpoint.ProviderSpecific{ + endpoint.ProviderSpecificProperty{ + Name: providerSpecificAlias, + Value: "true", + }, endpoint.ProviderSpecificProperty{ Name: providerSpecificEvaluateTargetHealth, Value: key, @@ -1682,6 +1695,10 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) { Targets: endpoint.Targets{"bar.eu-central-1.elb.amazonaws.com"}, RecordType: endpoint.RecordTypeCNAME, ProviderSpecific: endpoint.ProviderSpecific{ + endpoint.ProviderSpecificProperty{ + Name: providerSpecificAlias, + Value: "true", + }, endpoint.ProviderSpecificProperty{ Name: providerSpecificEvaluateTargetHealth, Value: key, @@ -1691,7 +1708,9 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) { }, } - require.NoError(t, provider.CreateRecords(context.Background(), records)) + require.NoError(t, provider.ApplyChanges(context.Background(), &plan.Changes{ + Create: records, + })) recordSets := listAWSRecords(t, provider.client, "/hostedzone/zone-1.ext-dns-test-2.teapot.zalan.do.") From 91744629c35eec86a4e734dab3193d0f489bdafa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 03:04:55 +0000 Subject: [PATCH 094/154] build(deps): bump golang from 1.19 to 1.20 Bumps golang from 1.19 to 1.20. --- updated-dependencies: - dependency-name: golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Dockerfile | 2 +- Dockerfile.mini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index db7d8dcca7..341df57028 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ # builder image ARG ARCH -FROM golang:1.19 as builder +FROM golang:1.20 as builder ARG ARCH WORKDIR /sigs.k8s.io/external-dns diff --git a/Dockerfile.mini b/Dockerfile.mini index 90cba37d9a..2428351aed 100644 --- a/Dockerfile.mini +++ b/Dockerfile.mini @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.19 as builder +FROM golang:1.20 as builder WORKDIR /sigs.k8s.io/external-dns From 93e7fcdb64b789ca5e3670dee9f2dfbfc67cc77f Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Fri, 9 Jun 2023 11:13:35 +0200 Subject: [PATCH 095/154] update go 1.20 on go.mod, docs & on ci --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docs.yml | 2 +- docs/contributing/getting-started.md | 2 +- go.mod | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3d36d5d53..173721737f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: 1.20 id: go - name: Check out code into the Go module directory @@ -38,7 +38,7 @@ jobs: apt update apt install -y make gcc libc-dev git if: github.actor == 'nektos/act' - + - name: Test run: make test diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bf37e27d3a..cadcb0488f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -30,7 +30,7 @@ jobs: - name: Install go version uses: actions/setup-go@v3 with: - go-version: '^1.19' + go-version: '^1.20' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 112048477a..aef5af4cc2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-go@v4 with: - go-version: ^1.19 + go-version: ^1.20 - run: | pip install -r docs/scripts/requirements.txt diff --git a/docs/contributing/getting-started.md b/docs/contributing/getting-started.md index 82976ee6d8..7cf42ca09f 100644 --- a/docs/contributing/getting-started.md +++ b/docs/contributing/getting-started.md @@ -1,7 +1,7 @@ # Quick Start - [Git](https://git-scm.com/downloads) -- [Go 1.19+](https://golang.org/dl/) +- [Go 1.20+](https://golang.org/dl/) - [Go modules](https://github.com/golang/go/wiki/Modules) - [golangci-lint](https://github.com/golangci/golangci-lint) - [Docker](https://docs.docker.com/install/) diff --git a/go.mod b/go.mod index 16af9aad9b..4d848314c7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module sigs.k8s.io/external-dns -go 1.19 +go 1.20 require ( cloud.google.com/go/compute/metadata v0.2.3 From de20b13879a32ba990502ac7fdfb3422370e27f2 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Fri, 9 Jun 2023 12:04:58 +0200 Subject: [PATCH 096/154] add golangci-lint update --- .github/workflows/lint.yaml | 2 +- .golangci.yml | 1 - provider/coredns/coredns.go | 2 +- provider/rdns/rdns.go | 2 +- provider/tencentcloud/cloudapi/mockapi.go | 2 +- source/fake.go | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 41b9880fa6..58465ce1fa 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -31,5 +31,5 @@ jobs: - name: Lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.50.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.2 make lint diff --git a/.golangci.yml b/.golangci.yml index 20c72e8c2e..e5a24cf6a9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,7 +19,6 @@ linters: # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint disable-all: true enable: - - depguard - dogsled - gofmt - goimports diff --git a/provider/coredns/coredns.go b/provider/coredns/coredns.go index 356ffee732..0d62552862 100644 --- a/provider/coredns/coredns.go +++ b/provider/coredns/coredns.go @@ -38,7 +38,7 @@ import ( ) func init() { - rand.Seed(time.Now().UnixNano()) + rand.New(rand.NewSource(time.Now().UnixNano())) } const ( diff --git a/provider/rdns/rdns.go b/provider/rdns/rdns.go index e645be0bc0..42feadcefd 100644 --- a/provider/rdns/rdns.go +++ b/provider/rdns/rdns.go @@ -46,7 +46,7 @@ const ( ) func init() { - rand.Seed(time.Now().UnixNano()) + rand.New(rand.NewSource(time.Now().UnixNano())) } // RDNSClient is an interface to work with Rancher DNS(RDNS) records in etcdv3 backend. diff --git a/provider/tencentcloud/cloudapi/mockapi.go b/provider/tencentcloud/cloudapi/mockapi.go index 424bd6102b..bdf6dabb2f 100644 --- a/provider/tencentcloud/cloudapi/mockapi.go +++ b/provider/tencentcloud/cloudapi/mockapi.go @@ -34,7 +34,7 @@ type mockAPIService struct { } func NewMockService(privateZones []*privatedns.PrivateZone, privateZoneRecords map[string][]*privatedns.PrivateZoneRecord, dnspodDomains []*dnspod.DomainListItem, dnspodRecords map[string][]*dnspod.RecordListItem) *mockAPIService { - rand.Seed(time.Now().Unix()) + rand.New(rand.NewSource(time.Now().Unix())) return &mockAPIService{ privateZones: privateZones, privateZoneRecords: privateZoneRecords, diff --git a/source/fake.go b/source/fake.go index 9173f4d0a1..1e3afadf9f 100644 --- a/source/fake.go +++ b/source/fake.go @@ -41,7 +41,7 @@ const ( ) func init() { - rand.Seed(time.Now().UnixNano()) + rand.New(rand.NewSource(time.Now().UnixNano())) } // NewFakeSource creates a new fakeSource with the given config. From 4b15f20e76c0e0e91d25b591a1f04d514ce947f0 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 8 Jun 2023 14:32:30 -0700 Subject: [PATCH 097/154] Simplify GetProviderSpecificProperty --- endpoint/endpoint.go | 8 ++++---- provider/aws/aws.go | 26 +++++++++++++------------- provider/scaleway/scaleway.go | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 736f1e5740..99b6d3f36e 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -230,14 +230,14 @@ func (e *Endpoint) WithProviderSpecific(key, value string) *Endpoint { return e } -// GetProviderSpecificProperty returns a ProviderSpecificProperty if the property exists. -func (e *Endpoint) GetProviderSpecificProperty(key string) (ProviderSpecificProperty, bool) { +// GetProviderSpecificProperty returns the value of a ProviderSpecificProperty if the property exists. +func (e *Endpoint) GetProviderSpecificProperty(key string) (string, bool) { for _, providerSpecific := range e.ProviderSpecific { if providerSpecific.Name == key { - return providerSpecific, true + return providerSpecific.Value, true } } - return ProviderSpecificProperty{}, false + return "", false } func (e *Endpoint) String() string { diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 45792e04ad..ac23eb7b8f 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -668,7 +668,7 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoin for _, ep := range endpoints { alias := false if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok { - alias = aliasString.Value == "true" + alias = aliasString == "true" } else if useAlias(ep, p.preferCNAME) { alias = true log.Debugf("Modifying endpoint: %v, setting %s=true", ep, providerSpecificAlias) @@ -706,7 +706,7 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C if targetHostedZone := isAWSAlias(ep); targetHostedZone != "" { evalTargetHealth := p.evaluateTargetHealth if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok { - evalTargetHealth = prop.Value == "true" + evalTargetHealth = prop == "true" } // If the endpoint has a Dualstack label, append a change for AAAA record as well. if val, ok := ep.Labels[endpoint.DualstackLabelKey]; ok { @@ -737,18 +737,18 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C if setIdentifier != "" { change.ResourceRecordSet.SetIdentifier = aws.String(setIdentifier) if prop, ok := ep.GetProviderSpecificProperty(providerSpecificWeight); ok { - weight, err := strconv.ParseInt(prop.Value, 10, 64) + weight, err := strconv.ParseInt(prop, 10, 64) if err != nil { - log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop.Value, err) + log.Errorf("Failed parsing value of %s: %s: %v; using weight of 0", providerSpecificWeight, prop, err) weight = 0 } change.ResourceRecordSet.Weight = aws.Int64(weight) } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificRegion); ok { - change.ResourceRecordSet.Region = aws.String(prop.Value) + change.ResourceRecordSet.Region = aws.String(prop) } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificFailover); ok { - change.ResourceRecordSet.Failover = aws.String(prop.Value) + change.ResourceRecordSet.Failover = aws.String(prop) } if _, ok := ep.GetProviderSpecificProperty(providerSpecificMultiValueAnswer); ok { change.ResourceRecordSet.MultiValueAnswer = aws.Bool(true) @@ -757,15 +757,15 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C geolocation := &route53.GeoLocation{} useGeolocation := false if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode); ok { - geolocation.ContinentCode = aws.String(prop.Value) + geolocation.ContinentCode = aws.String(prop) useGeolocation = true } else { if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode); ok { - geolocation.CountryCode = aws.String(prop.Value) + geolocation.CountryCode = aws.String(prop) useGeolocation = true } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode); ok { - geolocation.SubdivisionCode = aws.String(prop.Value) + geolocation.SubdivisionCode = aws.String(prop) useGeolocation = true } } @@ -775,7 +775,7 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok { - change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value) + change.ResourceRecordSet.HealthCheckId = aws.String(prop) } if ownedRecord, ok := ep.Labels[endpoint.OwnedRecordLabelKey]; ok { @@ -989,13 +989,13 @@ func useAlias(ep *endpoint.Endpoint, preferCNAME bool) bool { // isAWSAlias determines if a given endpoint is supposed to create an AWS Alias record // and (if so) returns the target hosted zone ID func isAWSAlias(ep *endpoint.Endpoint) string { - prop, exists := ep.GetProviderSpecificProperty(providerSpecificAlias) - if exists && prop.Value == "true" && ep.RecordType == endpoint.RecordTypeCNAME && len(ep.Targets) > 0 { + isAlias, exists := ep.GetProviderSpecificProperty(providerSpecificAlias) + if exists && isAlias == "true" && ep.RecordType == endpoint.RecordTypeCNAME && len(ep.Targets) > 0 { // alias records can only point to canonical hosted zones (e.g. to ELBs) or other records in the same zone if hostedZoneID, ok := ep.GetProviderSpecificProperty(providerSpecificTargetHostedZone); ok { // existing Endpoint where we got the target hosted zone from the Route53 data - return hostedZoneID.Value + return hostedZoneID } // check if the target is in a canonical hosted zone diff --git a/provider/scaleway/scaleway.go b/provider/scaleway/scaleway.go index 29969fb2cb..bd71aed254 100644 --- a/provider/scaleway/scaleway.go +++ b/provider/scaleway/scaleway.go @@ -278,9 +278,9 @@ func endpointToScalewayRecords(zoneName string, ep *endpoint.Endpoint) []*domain } priority := scalewayDefaultPriority if prop, ok := ep.GetProviderSpecificProperty(scalewayPriorityKey); ok { - prio, err := strconv.ParseUint(prop.Value, 10, 32) + prio, err := strconv.ParseUint(prop, 10, 32) if err != nil { - log.Errorf("Failed parsing value of %s: %s: %v; using priority of %d", scalewayPriorityKey, prop.Value, err, scalewayDefaultPriority) + log.Errorf("Failed parsing value of %s: %s: %v; using priority of %d", scalewayPriorityKey, prop, err, scalewayDefaultPriority) } else { priority = uint32(prio) } From 55bbb29f5501352fd795ac8f825f79ec955d1d39 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 8 Jun 2023 14:49:47 -0700 Subject: [PATCH 098/154] Route53 update configuration of target health checks --- endpoint/endpoint.go | 30 ++++++++++++++--- provider/aws/aws.go | 65 +++++++++++++++++++++---------------- provider/aws/aws_test.go | 70 ++++++++-------------------------------- provider/provider.go | 7 ++++ 4 files changed, 83 insertions(+), 89 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 99b6d3f36e..9c2c2138f3 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -222,11 +222,7 @@ func (e *Endpoint) WithSetIdentifier(setIdentifier string) *Endpoint { // warrant its own field on the Endpoint object itself. It differs from Labels in the fact that it's // not persisted in the Registry but only kept in memory during a single record synchronization. func (e *Endpoint) WithProviderSpecific(key, value string) *Endpoint { - if e.ProviderSpecific == nil { - e.ProviderSpecific = ProviderSpecific{} - } - - e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value}) + e.SetProviderSpecificProperty(key, value) return e } @@ -240,6 +236,30 @@ func (e *Endpoint) GetProviderSpecificProperty(key string) (string, bool) { return "", false } +// SetProviderSpecificProperty sets the value of a ProviderSpecificProperty. +func (e *Endpoint) SetProviderSpecificProperty(key string, value string) { + for i, providerSpecific := range e.ProviderSpecific { + if providerSpecific.Name == key { + e.ProviderSpecific[i] = ProviderSpecificProperty{ + Name: key, + Value: value, + } + return + } + } + + e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value}) +} + +func (e *Endpoint) DeleteProviderSpecificProperty(key string) { + for i, providerSpecific := range e.ProviderSpecific { + if providerSpecific.Name == key { + e.ProviderSpecific = append(e.ProviderSpecific[:i], e.ProviderSpecific[i+1:]...) + return + } + } +} + 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) } diff --git a/provider/aws/aws.go b/provider/aws/aws.go index ac23eb7b8f..be1997c7ed 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -47,10 +47,12 @@ const ( // As we are using the standard AWS client, this should already be compliant. // Hence, ifever AWS decides to raise this limit, we will automatically reduce the pressure on rate limits route53PageSize = "300" - // provider specific key that designates whether an AWS ALIAS record has the EvaluateTargetHealth - // field set to true. - providerSpecificAlias = "alias" - providerSpecificTargetHostedZone = "aws/target-hosted-zone" + // providerSpecificAlias specifies whether a CNAME endpoint maps to an AWS ALIAS record. + providerSpecificAlias = "alias" + providerSpecificTargetHostedZone = "aws/target-hosted-zone" + // providerSpecificEvaluateTargetHealth specifies whether an AWS ALIAS record + // has the EvaluateTargetHealth field set to true. Present iff the endpoint + // has a `providerSpecificAlias` value of `true`. providerSpecificEvaluateTargetHealth = "aws/evaluate-target-health" providerSpecificWeight = "aws/weight" providerSpecificRegion = "aws/region" @@ -283,13 +285,6 @@ func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) { return provider, nil } -func (p *AWSProvider) PropertyValuesEqual(name string, previous string, current string) bool { - if name == "aws/evaluate-target-health" { - return true - } - return p.BaseProvider.PropertyValuesEqual(name, previous, current) -} - // Zones returns the list of hosted zones. func (p *AWSProvider) Zones(ctx context.Context) (map[string]*route53.HostedZone, error) { if p.zonesCache.zones != nil && time.Since(p.zonesCache.age) < p.zonesCache.duration { @@ -390,7 +385,11 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos targets[idx] = aws.StringValue(rr.Value) } - newEndpoints = append(newEndpoints, endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...)) + ep := endpoint.NewEndpointWithTTL(wildcardUnescape(aws.StringValue(r.Name)), aws.StringValue(r.Type), ttl, targets...) + if aws.StringValue(r.Type) == endpoint.RecordTypeCNAME { + ep = ep.WithProviderSpecific(providerSpecificAlias, "false") + } + newEndpoints = append(newEndpoints, ep) } if r.AliasTarget != nil { @@ -466,8 +465,12 @@ func (p *AWSProvider) requiresDeleteCreate(old *endpoint.Endpoint, new *endpoint } // an ALIAS record change to/from a CNAME - if old.RecordType == endpoint.RecordTypeCNAME && useAlias(old, p.preferCNAME) != useAlias(new, p.preferCNAME) { - return true + if old.RecordType == endpoint.RecordTypeCNAME { + oldAlias, _ := old.GetProviderSpecificProperty(providerSpecificAlias) + newAlias, _ := new.GetProviderSpecificProperty(providerSpecificAlias) + if oldAlias != newAlias { + return true + } } // a set identifier change @@ -667,23 +670,29 @@ func (p *AWSProvider) newChanges(action string, endpoints []*endpoint.Endpoint) func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint { for _, ep := range endpoints { alias := false - if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok { + if ep.RecordType != endpoint.RecordTypeCNAME { + ep.DeleteProviderSpecificProperty(providerSpecificAlias) + } else if aliasString, ok := ep.GetProviderSpecificProperty(providerSpecificAlias); ok { alias = aliasString == "true" - } else if useAlias(ep, p.preferCNAME) { - alias = true - log.Debugf("Modifying endpoint: %v, setting %s=true", ep, providerSpecificAlias) - ep.ProviderSpecific = append(ep.ProviderSpecific, endpoint.ProviderSpecificProperty{ - Name: providerSpecificAlias, - Value: "true", - }) + if !alias && aliasString != "false" { + ep.SetProviderSpecificProperty(providerSpecificAlias, "false") + } + } else { + alias = useAlias(ep, p.preferCNAME) + log.Debugf("Modifying endpoint: %v, setting %s=%v", ep, providerSpecificAlias, alias) + ep.SetProviderSpecificProperty(providerSpecificAlias, strconv.FormatBool(alias)) } - if _, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); alias && !ok { - log.Debugf("Modifying endpoint: %v, setting %s=%t", ep, providerSpecificEvaluateTargetHealth, p.evaluateTargetHealth) - ep.ProviderSpecific = append(ep.ProviderSpecific, endpoint.ProviderSpecificProperty{ - Name: providerSpecificEvaluateTargetHealth, - Value: fmt.Sprintf("%t", p.evaluateTargetHealth), - }) + if alias { + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok { + if prop != "true" && prop != "false" { + ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, "false") + } + } else { + ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, strconv.FormatBool(p.evaluateTargetHealth)) + } + } else { + ep.DeleteProviderSpecificProperty(providerSpecificEvaluateTargetHealth) } } return endpoints diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 3a3fbf2581..4ed172d98b 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -494,7 +494,7 @@ func TestAWSRecords(t *testing.T) { records, err := provider.Records(context.Background()) require.NoError(t, err) - validateEndpoints(t, records, []*endpoint.Endpoint{ + validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpointWithTTL("list-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4"), endpoint.NewEndpointWithTTL("list-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), endpoint.NewEndpointWithTTL("*.wildcard-test.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8"), @@ -511,7 +511,7 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), endpoint.NewEndpointWithTTL("geolocation-subdivision-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationSubdivisionCode, "NY"), - endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), endpoint.NewEndpointWithTTL("mail.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeMX, endpoint.TTL(recordTTL), "10 mailhost1.example.com", "20 mailhost2.example.com"), }) @@ -529,11 +529,11 @@ func TestAWSAdjustEndpoints(t *testing.T) { endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health } - provider.AdjustEndpoints(records) + records = provider.AdjustEndpoints(records) - validateEndpoints(t, records, []*endpoint.Endpoint{ + validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), - endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com"), + endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), @@ -1426,7 +1426,7 @@ func TestAWSsubmitChanges(t *testing.T) { records, err := provider.Records(ctx) require.NoError(t, err) - validateEndpoints(t, records, endpoints) + validateEndpoints(t, provider, records, endpoints) } func TestAWSsubmitChangesError(t *testing.T) { @@ -1607,8 +1607,11 @@ func TestAWSBatchChangeSetExceedingNameChange(t *testing.T) { require.Equal(t, 0, len(batchCs)) } -func validateEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) { +func validateEndpoints(t *testing.T, provider *AWSProvider, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) { assert.True(t, testutils.SameEndpoints(endpoints, expected), "actual and expected endpoints don't match. %+v:%+v", endpoints, expected) + + normalized := provider.AdjustEndpoints(endpoints) + assert.True(t, testutils.SameEndpoints(normalized, expected), "actual and normalized endpoints don't match. %+v:%+v", endpoints, normalized) } func validateAWSZones(t *testing.T, zones map[string]*route53.HostedZone, expected map[string]*route53.HostedZone) { @@ -1840,51 +1843,6 @@ func TestAWSSuitableZones(t *testing.T) { } } -func TestAWSHealthTargetAnnotation(tt *testing.T) { - comparator := func(name, previous, current string) bool { - return previous == current - } - for _, test := range []struct { - name string - current *endpoint.Endpoint - desired *endpoint.Endpoint - propertyComparator func(name, previous, current string) bool - shouldUpdate bool - }{ - { - name: "skip AWS target health", - current: &endpoint.Endpoint{ - RecordType: "A", - DNSName: "foo.com", - ProviderSpecific: []endpoint.ProviderSpecificProperty{ - {Name: "aws/evaluate-target-health", Value: "true"}, - }, - }, - desired: &endpoint.Endpoint{ - DNSName: "foo.com", - RecordType: "A", - ProviderSpecific: []endpoint.ProviderSpecificProperty{ - {Name: "aws/evaluate-target-health", Value: "false"}, - }, - }, - propertyComparator: comparator, - shouldUpdate: false, - }, - } { - tt.Run(test.name, func(t *testing.T) { - provider := &AWSProvider{} - plan := &plan.Plan{ - Current: []*endpoint.Endpoint{test.current}, - Desired: []*endpoint.Endpoint{test.desired}, - PropertyComparator: provider.PropertyValuesEqual, - ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}, - } - plan = plan.Calculate() - assert.Equal(t, test.shouldUpdate, len(plan.Changes.UpdateNew) == 1) - }) - } -} - func createAWSZone(t *testing.T, provider *AWSProvider, zone *route53.HostedZone) { params := &route53.CreateHostedZoneInput{ CallerReference: aws.String("external-dns.alpha.kubernetes.io/test-zone"), @@ -1908,7 +1866,7 @@ func setAWSRecords(t *testing.T, provider *AWSProvider, records []*route53.Resou endpoints, err := provider.Records(ctx) require.NoError(t, err) - validateEndpoints(t, endpoints, []*endpoint.Endpoint{}) + validateEndpoints(t, provider, endpoints, []*endpoint.Endpoint{}) var changes Route53Changes for _, record := range records { @@ -2071,13 +2029,13 @@ func TestRequiresDeleteCreate(t *testing.T) { provider, _ := newAWSProvider(t, endpoint.NewDomainFilter([]string{"foo.bar."}), provider.NewZoneIDFilter([]string{}), provider.NewZoneTypeFilter(""), defaultEvaluateTargetHealth, false, nil) oldRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "8.8.8.8") - newRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar") + newRecordType := endpoint.NewEndpointWithTTL("recordType", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar").WithProviderSpecific(providerSpecificAlias, "false") assert.False(t, provider.requiresDeleteCreate(oldRecordType, oldRecordType), "actual and expected endpoints don't match. %+v:%+v", oldRecordType, oldRecordType) assert.True(t, provider.requiresDeleteCreate(oldRecordType, newRecordType), "actual and expected endpoints don't match. %+v:%+v", oldRecordType, newRecordType) - oldCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar") - newCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.us-east-1.elb.amazonaws.com") + oldCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar").WithProviderSpecific(providerSpecificAlias, "false") + newCNAMEAlias := endpoint.NewEndpointWithTTL("CNAMEAlias", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "bar.us-east-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true") assert.False(t, provider.requiresDeleteCreate(oldCNAMEAlias, oldCNAMEAlias), "actual and expected endpoints don't match. %+v:%+v", oldCNAMEAlias, oldCNAMEAlias.DNSName) assert.True(t, provider.requiresDeleteCreate(oldCNAMEAlias, newCNAMEAlias), "actual and expected endpoints don't match. %+v:%+v", oldCNAMEAlias, newCNAMEAlias) diff --git a/provider/provider.go b/provider/provider.go index 06791204dc..3c8d358f17 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -30,6 +30,13 @@ type Provider interface { Records(ctx context.Context) ([]*endpoint.Endpoint, error) ApplyChanges(ctx context.Context, changes *plan.Changes) error PropertyValuesEqual(name string, previous string, current string) bool + // AdjustEndpoints canonicalizes a set of candidate endpoints. + // It is called with a set of candidate endpoints obtained from the various sources. + // It returns a set modified as required by the provider. The provider is responsible for + // adding, removing, and modifying the ProviderSpecific properties to match + // the endpoints that the provider returns in `Records` so that the change plan will not have + // unnecessary (potentially failing) changes. It may also modify other fields, add, or remove + // Endpoints. It is permitted to modify the supplied endpoints. AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint GetDomainFilter() endpoint.DomainFilterInterface } From e86656771805835b6761b05b1f9e8716147efb39 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Mon, 12 Jun 2023 08:55:52 +0200 Subject: [PATCH 099/154] fix: yaml parsing of go version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 173721737f..5194ed0dcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: 1.20 + go-version: '1.20' id: go - name: Check out code into the Go module directory From dc069cc10ff9b16a86cdadd7636e3c7733c95a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Mon, 12 Jun 2023 10:44:29 +0200 Subject: [PATCH 100/154] refactor: use always fmt.Errorf("...: %w", err), instead of %s or %v MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- pkg/tlsutils/tlsconfig.go | 6 +++--- provider/akamai/akamai.go | 2 +- provider/coredns/coredns.go | 8 ++++---- provider/infoblox/infoblox.go | 12 ++++++------ provider/rdns/rdns.go | 10 +++++----- provider/transip/transip.go | 2 +- source/crd.go | 2 +- source/node.go | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pkg/tlsutils/tlsconfig.go b/pkg/tlsutils/tlsconfig.go index 3a25334971..5275fad135 100644 --- a/pkg/tlsutils/tlsconfig.go +++ b/pkg/tlsutils/tlsconfig.go @@ -51,7 +51,7 @@ func NewTLSConfig(certPath, keyPath, caPath, serverName string, insecure bool, m if certPath != "" { cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { - return nil, fmt.Errorf("could not load TLS cert: %s", err) + return nil, fmt.Errorf("could not load TLS cert: %w", err) } certificates = append(certificates, cert) } @@ -78,11 +78,11 @@ func loadRoots(caPath string) (*x509.CertPool, error) { roots := x509.NewCertPool() pem, err := os.ReadFile(caPath) if err != nil { - return nil, fmt.Errorf("error reading %s: %s", caPath, err) + return nil, fmt.Errorf("error reading %s: %w", caPath, err) } ok := roots.AppendCertsFromPEM(pem) if !ok { - return nil, fmt.Errorf("could not read root certs: %s", err) + return nil, fmt.Errorf("could not read root certs: %w", err) } return roots, nil } diff --git a/provider/akamai/akamai.go b/provider/akamai/akamai.go index f59bd384f0..290b423ae6 100644 --- a/provider/akamai/akamai.go +++ b/provider/akamai/akamai.go @@ -426,7 +426,7 @@ func (p AkamaiProvider) deleteRecordsets(zoneNameIDMapper provider.ZoneIDName, e rec, err := p.client.GetRecord(zoneName, recName, endpoint.RecordType) if err != nil { if _, ok := err.(*dns.RecordError); !ok { - return fmt.Errorf("endpoint deletion. record validation failed. error: %s", err.Error()) + return fmt.Errorf("endpoint deletion. record validation failed. error: %w", err) } log.Infof("Endpoint deletion. Record doesn't exist. Name: %s, Type: %s", recName, endpoint.RecordType) continue diff --git a/provider/coredns/coredns.go b/provider/coredns/coredns.go index 356ffee732..0e36bc2e23 100644 --- a/provider/coredns/coredns.go +++ b/provider/coredns/coredns.go @@ -112,7 +112,7 @@ func (c etcdClient) GetServices(prefix string) ([]*Service, error) { for _, n := range r.Kvs { svc := new(Service) if err := json.Unmarshal(n.Value, svc); err != nil { - return nil, fmt.Errorf("%s: %s", n.Key, err.Error()) + return nil, fmt.Errorf("%s: %w", n.Key, err) } b := Service{Host: svc.Host, Port: svc.Port, Priority: svc.Priority, Weight: svc.Weight, Text: svc.Text, Key: string(n.Key)} if _, ok := bx[b]; ok { @@ -166,7 +166,7 @@ func newTLSConfig(certPath, keyPath, caPath, serverName string, insecure bool) ( if certPath != "" { cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { - return nil, fmt.Errorf("could not load TLS cert: %s", err) + return nil, fmt.Errorf("could not load TLS cert: %w", err) } certificates = append(certificates, cert) } @@ -192,11 +192,11 @@ func loadRoots(caPath string) (*x509.CertPool, error) { roots := x509.NewCertPool() pem, err := os.ReadFile(caPath) if err != nil { - return nil, fmt.Errorf("error reading %s: %s", caPath, err) + return nil, fmt.Errorf("error reading %s: %w", caPath, err) } ok := roots.AppendCertsFromPEM(pem) if !ok { - return nil, fmt.Errorf("could not read root certs: %s", err) + return nil, fmt.Errorf("could not read root certs: %w", err) } return roots, nil } diff --git a/provider/infoblox/infoblox.go b/provider/infoblox/infoblox.go index c15e9dc897..bea9321667 100644 --- a/provider/infoblox/infoblox.go +++ b/provider/infoblox/infoblox.go @@ -187,7 +187,7 @@ func NewInfobloxProvider(ibStartupCfg StartupConfig) (*ProviderConfig, error) { func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.Endpoint, err error) { zones, err := p.zones() if err != nil { - return nil, fmt.Errorf("could not fetch zones: %s", err) + return nil, fmt.Errorf("could not fetch zones: %w", err) } for _, zone := range zones { @@ -211,7 +211,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End objA.Zone = zone.Fqdn err = p.client.GetObject(objA, "", searchParams, &resA) if err != nil && !isNotFoundError(err) { - return nil, fmt.Errorf("could not fetch A records from zone '%s': %s", zone.Fqdn, err) + return nil, fmt.Errorf("could not fetch A records from zone '%s': %w", zone.Fqdn, err) } for _, res := range resA { // Check if endpoint already exists and add to existing endpoint if it does @@ -257,7 +257,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End objH.Zone = zone.Fqdn err = p.client.GetObject(objH, "", searchParams, &resH) if err != nil && !isNotFoundError(err) { - return nil, fmt.Errorf("could not fetch host records from zone '%s': %s", zone.Fqdn, err) + return nil, fmt.Errorf("could not fetch host records from zone '%s': %w", zone.Fqdn, err) } for _, res := range resH { for _, ip := range res.Ipv4Addrs { @@ -279,7 +279,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End objC.Zone = zone.Fqdn err = p.client.GetObject(objC, "", searchParams, &resC) if err != nil && !isNotFoundError(err) { - return nil, fmt.Errorf("could not fetch CNAME records from zone '%s': %s", zone.Fqdn, err) + return nil, fmt.Errorf("could not fetch CNAME records from zone '%s': %w", zone.Fqdn, err) } for _, res := range resC { logrus.Debugf("Record='%s' CNAME:'%s'", res.Name, res.Canonical) @@ -298,7 +298,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End objP.View = p.view err = p.client.GetObject(objP, "", searchParams, &resP) if err != nil && !isNotFoundError(err) { - return nil, fmt.Errorf("could not fetch PTR records from zone '%s': %s", zone.Fqdn, err) + return nil, fmt.Errorf("could not fetch PTR records from zone '%s': %w", zone.Fqdn, err) } for _, res := range resP { endpoints = append(endpoints, endpoint.NewEndpoint(res.PtrdName, endpoint.RecordTypePTR, res.Ipv4Addr)) @@ -315,7 +315,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End ) err = p.client.GetObject(objT, "", searchParams, &resT) if err != nil && !isNotFoundError(err) { - return nil, fmt.Errorf("could not fetch TXT records from zone '%s': %s", zone.Fqdn, err) + return nil, fmt.Errorf("could not fetch TXT records from zone '%s': %w", zone.Fqdn, err) } for _, res := range resT { // The Infoblox API strips enclosing double quotes from TXT records lacking whitespace. diff --git a/provider/rdns/rdns.go b/provider/rdns/rdns.go index e645be0bc0..7d9c88806a 100644 --- a/provider/rdns/rdns.go +++ b/provider/rdns/rdns.go @@ -295,7 +295,7 @@ func newEtcdv3Client() (RDNSClient, error) { if cert != "" { cert, err := tls.LoadX509KeyPair(cert, key) if err != nil { - return nil, fmt.Errorf("could not load TLS cert: %s", err) + return nil, fmt.Errorf("could not load TLS cert: %w", err) } certificates = append(certificates, cert) } @@ -310,11 +310,11 @@ func newEtcdv3Client() (RDNSClient, error) { roots := x509.NewCertPool() pem, err := os.ReadFile(ca) if err != nil { - return nil, fmt.Errorf("error reading %s: %s", ca, err) + return nil, fmt.Errorf("error reading %s: %w", ca, err) } ok := roots.AppendCertsFromPEM(pem) if !ok { - return nil, fmt.Errorf("could not read root certs: %s", err) + return nil, fmt.Errorf("could not read root certs: %w", err) } config.RootCAs = roots } @@ -347,7 +347,7 @@ func (c etcdv3Client) Get(key string) ([]RDNSRecord, error) { for _, v := range result.Kvs { r := new(RDNSRecord) if err := json.Unmarshal(v.Value, r); err != nil { - return nil, fmt.Errorf("%s: %s", v.Key, err.Error()) + return nil, fmt.Errorf("%s: %w", v.Key, err) } r.Key = string(v.Key) rs = append(rs, *r) @@ -412,7 +412,7 @@ func (c etcdv3Client) aggregationRecords(result *clientv3.GetResponse) ([]RDNSRe for _, n := range result.Kvs { r := new(RDNSRecord) if err := json.Unmarshal(n.Value, r); err != nil { - return nil, fmt.Errorf("%s: %s", n.Key, err.Error()) + return nil, fmt.Errorf("%s: %w", n.Key, err) } r.Key = string(n.Key) diff --git a/provider/transip/transip.go b/provider/transip/transip.go index 6543da9151..af8992383a 100644 --- a/provider/transip/transip.go +++ b/provider/transip/transip.go @@ -72,7 +72,7 @@ func NewTransIPProvider(accountName, privateKeyFile string, domainFilter endpoin Mode: apiMode, }) if err != nil { - return nil, fmt.Errorf("could not setup TransIP API client: %s", err.Error()) + return nil, fmt.Errorf("could not setup TransIP API client: %w", err) } // return TransIPProvider struct diff --git a/source/crd.go b/source/crd.go index b32b93e6e3..10be3fccea 100644 --- a/source/crd.go +++ b/source/crd.go @@ -79,7 +79,7 @@ func NewCRDClientForAPIVersionKind(client kubernetes.Interface, kubeConfig, apiS } apiResourceList, err := client.Discovery().ServerResourcesForGroupVersion(groupVersion.String()) if err != nil { - return nil, nil, fmt.Errorf("error listing resources in GroupVersion %q: %s", groupVersion.String(), err) + return nil, nil, fmt.Errorf("error listing resources in GroupVersion %q: %w", groupVersion.String(), err) } var crdAPIResource *metav1.APIResource diff --git a/source/node.go b/source/node.go index 5e287e9a00..63af289f8d 100644 --- a/source/node.go +++ b/source/node.go @@ -130,7 +130,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro addrs, err := ns.nodeAddresses(node) if err != nil { - return nil, fmt.Errorf("failed to get node address from %s: %s", node.Name, err.Error()) + return nil, fmt.Errorf("failed to get node address from %s: %w", node.Name, err) } ep.Labels = endpoint.NewLabels() From 7fa786733a020e7921840b91053f626e0577604e Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Mon, 12 Jun 2023 12:08:35 +0200 Subject: [PATCH 101/154] review: remove seed and init() func --- .github/workflows/docs.yml | 2 +- provider/coredns/coredns.go | 4 ---- provider/tencentcloud/cloudapi/mockapi.go | 2 -- source/fake.go | 5 ----- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index aef5af4cc2..b5a7decd88 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-go@v4 with: - go-version: ^1.20 + go-version: '^1.20' - run: | pip install -r docs/scripts/requirements.txt diff --git a/provider/coredns/coredns.go b/provider/coredns/coredns.go index 0d62552862..c76525e298 100644 --- a/provider/coredns/coredns.go +++ b/provider/coredns/coredns.go @@ -37,10 +37,6 @@ import ( "sigs.k8s.io/external-dns/provider" ) -func init() { - rand.New(rand.NewSource(time.Now().UnixNano())) -} - const ( priority = 10 // default priority when nothing is set etcdTimeout = 5 * time.Second diff --git a/provider/tencentcloud/cloudapi/mockapi.go b/provider/tencentcloud/cloudapi/mockapi.go index bdf6dabb2f..707579f008 100644 --- a/provider/tencentcloud/cloudapi/mockapi.go +++ b/provider/tencentcloud/cloudapi/mockapi.go @@ -18,7 +18,6 @@ package cloudapi import ( "math/rand" - "time" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323" @@ -34,7 +33,6 @@ type mockAPIService struct { } func NewMockService(privateZones []*privatedns.PrivateZone, privateZoneRecords map[string][]*privatedns.PrivateZoneRecord, dnspodDomains []*dnspod.DomainListItem, dnspodRecords map[string][]*dnspod.RecordListItem) *mockAPIService { - rand.New(rand.NewSource(time.Now().Unix())) return &mockAPIService{ privateZones: privateZones, privateZoneRecords: privateZoneRecords, diff --git a/source/fake.go b/source/fake.go index 1e3afadf9f..2041c116e4 100644 --- a/source/fake.go +++ b/source/fake.go @@ -25,7 +25,6 @@ import ( "fmt" "math/rand" "net" - "time" "sigs.k8s.io/external-dns/endpoint" ) @@ -40,10 +39,6 @@ const ( defaultFQDNTemplate = "example.com" ) -func init() { - rand.New(rand.NewSource(time.Now().UnixNano())) -} - // NewFakeSource creates a new fakeSource with the given config. func NewFakeSource(fqdnTemplate string) (Source, error) { if fqdnTemplate == "" { From ee5dc1bdda4373acc70338d01bb886db38885d65 Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Mon, 12 Jun 2023 17:52:34 +0200 Subject: [PATCH 102/154] enable dependabot grouped updates --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1897a3ebd3..71cf5da00d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,11 +9,23 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" + groups: + dev-dependencies: + patterns: + - "*" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" + groups: + dev-dependencies: + patterns: + - "*" - package-ecosystem: "docker" # Keep Docker dependencies up to date directory: "/" schedule: interval: "daily" + groups: + dev-dependencies: + patterns: + - "*" From adb88032ce73d0ba30932a01f41cfd7ba21b696c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 04:00:56 +0000 Subject: [PATCH 103/154] build(deps): bump the dev-dependencies group with 4 updates Bumps the dev-dependencies group with 4 updates: [actions/github-script](https://github.com/actions/github-script), [GrantBirki/json-yaml-validate](https://github.com/GrantBirki/json-yaml-validate), [helm/chart-testing-action](https://github.com/helm/chart-testing-action) and [helm/kind-action](https://github.com/helm/kind-action). Updates `actions/github-script` from 6.3.3 to 6.4.1 - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/d556feaca394842dc55e4734bf3bb9f685482fa0...d7906e4ad0b1822421a7e6a35d5ca353c962f410) Updates `GrantBirki/json-yaml-validate` from 1.2.0 to 1.4.0 - [Release notes](https://github.com/GrantBirki/json-yaml-validate/releases) - [Commits](https://github.com/GrantBirki/json-yaml-validate/compare/v1.2.0...v1.4.0) Updates `helm/chart-testing-action` from 2.3.1 to 2.4.0 - [Release notes](https://github.com/helm/chart-testing-action/releases) - [Commits](https://github.com/helm/chart-testing-action/compare/afea100a513515fbd68b0e72a7bb0ae34cb62aec...e8788873172cb653a90ca2e819d79d65a66d4e76) Updates `helm/kind-action` from 1.5.0 to 1.7.0 - [Release notes](https://github.com/helm/kind-action/releases) - [Commits](https://github.com/helm/kind-action/compare/d8ccf8fb623ce1bb360ae2f45f323d9d5c5e9f00...fa81e57adff234b2908110485695db0f181f3c67) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: GrantBirki/json-yaml-validate dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: helm/chart-testing-action dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: helm/kind-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/gh-workflow-approve.yaml | 2 +- .github/workflows/json-yaml-validate.yml | 2 +- .github/workflows/lint-test-chart.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gh-workflow-approve.yaml b/.github/workflows/gh-workflow-approve.yaml index c0dc99008d..e3c13fdd98 100644 --- a/.github/workflows/gh-workflow-approve.yaml +++ b/.github/workflows/gh-workflow-approve.yaml @@ -17,7 +17,7 @@ jobs: actions: write steps: - name: Update PR - uses: actions/github-script@d556feaca394842dc55e4734bf3bb9f685482fa0 # v6.3.3 + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 continue-on-error: true with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/json-yaml-validate.yml b/.github/workflows/json-yaml-validate.yml index 1eb833f636..1e71e7547d 100644 --- a/.github/workflows/json-yaml-validate.yml +++ b/.github/workflows/json-yaml-validate.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - name: json-yaml-validate - uses: GrantBirki/json-yaml-validate@v1.2.0 + uses: GrantBirki/json-yaml-validate@v1.4.0 with: comment: "true" # enable comment mode yaml_exclude_regex: "(charts/external-dns/templates.*|mkdocs.yml)" diff --git a/.github/workflows/lint-test-chart.yaml b/.github/workflows/lint-test-chart.yaml index f8207ef507..2f6025cf08 100644 --- a/.github/workflows/lint-test-chart.yaml +++ b/.github/workflows/lint-test-chart.yaml @@ -38,7 +38,7 @@ jobs: python-version: "3.x" - name: Set-up chart-testing - uses: helm/chart-testing-action@afea100a513515fbd68b0e72a7bb0ae34cb62aec + uses: helm/chart-testing-action@e8788873172cb653a90ca2e819d79d65a66d4e76 - name: Run chart-testing (list-changed) id: list-changed @@ -52,7 +52,7 @@ jobs: run: ct lint --check-version-increment=false - name: Set-up Kind cluster - uses: helm/kind-action@d8ccf8fb623ce1bb360ae2f45f323d9d5c5e9f00 + uses: helm/kind-action@fa81e57adff234b2908110485695db0f181f3c67 with: wait: 120s if: steps.list-changed.outputs.changed == 'true' From beb893df7d25e8b5ea254161172f8dc8ae1dc94b Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Mon, 12 Jun 2023 21:28:18 -0700 Subject: [PATCH 104/154] Address review comment --- endpoint/endpoint.go | 1 + 1 file changed, 1 insertion(+) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 9c2c2138f3..e1ed83c5b4 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -251,6 +251,7 @@ func (e *Endpoint) SetProviderSpecificProperty(key string, value string) { e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value}) } +// DeleteProviderSpecificProperty deletes any ProviderSpecificProperty of the specified name. func (e *Endpoint) DeleteProviderSpecificProperty(key string) { for i, providerSpecific := range e.ProviderSpecific { if providerSpecific.Name == key { From 758e8cd1d9b24914f160430966250dd7efe82b77 Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Tue, 13 Jun 2023 12:43:02 +0200 Subject: [PATCH 105/154] bump github.com/gophercloud/gophercloud and github.com/Azure/azure-sdk-for-go Signed-off-by: Raffaele Di Fazio --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 4d848314c7..eabcd3d92c 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 github.com/go-gandi/go-gandi v0.6.0 github.com/google/go-cmp v0.5.9 - github.com/gophercloud/gophercloud v0.25.0 + github.com/gophercloud/gophercloud v1.4.0 github.com/hooklift/gowsdl v0.5.0 github.com/infobloxopen/infoblox-go-client/v2 v2.1.2-0.20220407114022-6f4c71443168 github.com/linki/instrumented_http v0.3.0 diff --git a/go.sum b/go.sum index cb1d8eea52..abc1d56059 100644 --- a/go.sum +++ b/go.sum @@ -594,6 +594,8 @@ github.com/gookit/color v1.2.3/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1K github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= +github.com/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= +github.com/gophercloud/gophercloud v1.4.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= 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= @@ -1267,6 +1269,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= From 41ee9e8e48cef0b441d1d9a9a303fc95ecbf5fa6 Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Tue, 13 Jun 2023 12:44:30 +0200 Subject: [PATCH 106/154] bump github.com/IBM/go-sdk-core/v5 and transitive deps Signed-off-by: Raffaele Di Fazio --- go.mod | 29 +++++++++++++++-------------- go.sum | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index eabcd3d92c..fb7c3ca3d2 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 - github.com/IBM/go-sdk-core/v5 v5.8.0 + github.com/IBM/go-sdk-core/v5 v5.13.4 github.com/IBM/networking-go-sdk v0.36.0 github.com/StackExchange/dnscontrol/v3 v3.27.1 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 @@ -61,7 +61,7 @@ require ( go.etcd.io/etcd/api/v3 v3.5.8 go.etcd.io/etcd/client/v3 v3.5.8 go.uber.org/ratelimit v0.2.0 - golang.org/x/net v0.7.0 + golang.org/x/net v0.8.0 golang.org/x/oauth2 v0.5.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.110.0 @@ -92,7 +92,7 @@ require ( github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/ans-group/go-durationstring v1.2.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect @@ -104,13 +104,14 @@ require ( github.com/fatih/structs v1.1.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.3 // indirect - github.com/go-openapi/errors v0.19.8 // indirect + github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/strfmt v0.20.2 // indirect + github.com/go-openapi/strfmt v0.21.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect - github.com/go-playground/locales v0.14.0 // indirect - github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.13.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -141,7 +142,7 @@ require ( 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/leodido/go-urn v1.2.1 // indirect + github.com/leodido/go-urn v1.2.3 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect @@ -171,18 +172,18 @@ require ( github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/vektah/gqlparser/v2 v2.5.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.8 // indirect - go.mongodb.org/mongo-driver v1.5.1 // indirect + go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/mod v0.7.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/mod v0.8.0 // indirect golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.3.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect google.golang.org/grpc v1.53.0 // indirect diff --git a/go.sum b/go.sum index abc1d56059..da9dc3fae6 100644 --- a/go.sum +++ b/go.sum @@ -88,6 +88,8 @@ github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= +github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= +github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= github.com/IBM/networking-go-sdk v0.36.0 h1:ADntTsRM8DMZOxS9TYGTAL6i0zw9V2L7OeLFd9Czntk= github.com/IBM/networking-go-sdk v0.36.0/go.mod h1:tDJtlySQC/txyejU9KeQ27Amc6xKH0MwHFE/B2+Sn5w= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -167,6 +169,8 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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= @@ -380,6 +384,9 @@ github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQH github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= 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= @@ -414,6 +421,8 @@ github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+Z github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlONADE= github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= +github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= 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= @@ -428,11 +437,17 @@ github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvSc github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ= +github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -737,6 +752,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o 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/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 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= @@ -760,6 +776,8 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6Fm github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= +github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= github.com/lestrrat-go/codegen v1.0.2/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= @@ -1170,7 +1188,9 @@ github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZ github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= @@ -1209,6 +1229,9 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= +go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= 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= @@ -1268,10 +1291,13 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1308,6 +1334,7 @@ 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.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1368,6 +1395,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= 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= @@ -1491,6 +1520,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1504,6 +1535,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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= @@ -1585,6 +1618,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 09a3e835415895317d2c4e4de8aedb3e4c8f75eb Mon Sep 17 00:00:00 2001 From: Raffaele Di Fazio Date: Tue, 13 Jun 2023 12:45:18 +0200 Subject: [PATCH 107/154] bump github.com/bodgit/tsig Signed-off-by: Raffaele Di Fazio --- go.mod | 8 ++++---- go.sum | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index fb7c3ca3d2..227ccc6081 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/aliyun/alibaba-cloud-sdk-go v1.62.4 github.com/ans-group/sdk-go v1.10.4 github.com/aws/aws-sdk-go v1.44.136 - github.com/bodgit/tsig v1.2.0 + github.com/bodgit/tsig v1.2.2 github.com/civo/civogo v0.3.14 github.com/cloudflare/cloudflare-go v0.58.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 @@ -130,13 +130,13 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.2 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect - github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect github.com/jcmturner/goidentity/v6 v6.0.1 // indirect - github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/go.sum b/go.sum index da9dc3fae6..ae19339555 100644 --- a/go.sum +++ b/go.sum @@ -194,6 +194,8 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= +github.com/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= +github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= 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= @@ -667,6 +669,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/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= @@ -702,10 +706,14 @@ github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8 github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE/Tq8= +github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= @@ -846,6 +854,7 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.6/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -1334,6 +1343,7 @@ 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.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/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= @@ -1386,11 +1396,13 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= @@ -1615,9 +1627,11 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From bd67905307883d4b814309062ca2471bd3720531 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 14 Jun 2023 18:08:10 +0200 Subject: [PATCH 108/154] Added support for new traefik CRDs Signed-off-by: Thomas Kosiewski --- source/traefik_proxy.go | 258 +++++++++++++- source/traefik_proxy_test.go | 656 +++++++++++++++++++++++++++++++++++ 2 files changed, 896 insertions(+), 18 deletions(-) diff --git a/source/traefik_proxy.go b/source/traefik_proxy.go index ffdd791f27..38bc75b3ee 100644 --- a/source/traefik_proxy.go +++ b/source/traefik_proxy.go @@ -42,16 +42,31 @@ import ( var ( ingressrouteGVR = schema.GroupVersionResource{ - Group: "traefik.containo.us", + Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutes", } ingressrouteTCPGVR = schema.GroupVersionResource{ - Group: "traefik.containo.us", + Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutetcps", } ingressrouteUDPGVR = schema.GroupVersionResource{ + Group: "traefik.io", + Version: "v1alpha1", + Resource: "ingressrouteudps", + } + oldIngressrouteGVR = schema.GroupVersionResource{ + Group: "traefik.containo.us", + Version: "v1alpha1", + Resource: "ingressroutes", + } + oldIngressrouteTCPGVR = schema.GroupVersionResource{ + Group: "traefik.containo.us", + Version: "v1alpha1", + Resource: "ingressroutetcps", + } + oldIngressrouteUDPGVR = schema.GroupVersionResource{ Group: "traefik.containo.us", Version: "v1alpha1", Resource: "ingressrouteudps", @@ -64,14 +79,17 @@ var ( ) type traefikSource struct { - annotationFilter string - dynamicKubeClient dynamic.Interface - ingressRouteInformer informers.GenericInformer - ingressRouteTcpInformer informers.GenericInformer - ingressRouteUdpInformer informers.GenericInformer - kubeClient kubernetes.Interface - namespace string - unstructuredConverter *unstructuredConverter + annotationFilter string + dynamicKubeClient dynamic.Interface + ingressRouteInformer informers.GenericInformer + ingressRouteTcpInformer informers.GenericInformer + ingressRouteUdpInformer informers.GenericInformer + oldIngressRouteInformer informers.GenericInformer + oldIngressRouteTcpInformer informers.GenericInformer + oldIngressRouteUdpInformer informers.GenericInformer + kubeClient kubernetes.Interface + namespace string + unstructuredConverter *unstructuredConverter } func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, kubeClient kubernetes.Interface, namespace string, annotationFilter string) (Source, error) { @@ -81,6 +99,9 @@ func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, ingressRouteInformer := informerFactory.ForResource(ingressrouteGVR) ingressRouteTcpInformer := informerFactory.ForResource(ingressrouteTCPGVR) ingressRouteUdpInformer := informerFactory.ForResource(ingressrouteUDPGVR) + oldIngressRouteInformer := informerFactory.ForResource(oldIngressrouteGVR) + oldIngressRouteTcpInformer := informerFactory.ForResource(oldIngressrouteTCPGVR) + oldIngressRouteUdpInformer := informerFactory.ForResource(oldIngressrouteUDPGVR) // Add default resource event handlers to properly initialize informers. ingressRouteInformer.Informer().AddEventHandler( @@ -98,6 +119,21 @@ func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, AddFunc: func(obj interface{}) {}, }, ) + oldIngressRouteInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) + oldIngressRouteTcpInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) + oldIngressRouteUdpInformer.Informer().AddEventHandler( + cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) {}, + }, + ) informerFactory.Start((ctx.Done())) @@ -112,14 +148,17 @@ func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, } return &traefikSource{ - annotationFilter: annotationFilter, - dynamicKubeClient: dynamicKubeClient, - ingressRouteInformer: ingressRouteInformer, - ingressRouteTcpInformer: ingressRouteTcpInformer, - ingressRouteUdpInformer: ingressRouteUdpInformer, - kubeClient: kubeClient, - namespace: namespace, - unstructuredConverter: uc, + annotationFilter: annotationFilter, + dynamicKubeClient: dynamicKubeClient, + ingressRouteInformer: ingressRouteInformer, + ingressRouteTcpInformer: ingressRouteTcpInformer, + ingressRouteUdpInformer: ingressRouteUdpInformer, + oldIngressRouteInformer: oldIngressRouteInformer, + oldIngressRouteTcpInformer: oldIngressRouteTcpInformer, + oldIngressRouteUdpInformer: oldIngressRouteUdpInformer, + kubeClient: kubeClient, + namespace: namespace, + unstructuredConverter: uc, }, nil } @@ -130,18 +169,33 @@ func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e if err != nil { return nil, err } + oldIngressRouteEndpoints, err := ts.oldIngressRouteEndpoints() + if err != nil { + return nil, err + } ingressRouteTCPEndpoints, err := ts.ingressRouteTCPEndpoints() if err != nil { return nil, err } + oldIngressRouteTCPEndpoints, err := ts.oldIngressRouteTCPEndpoints() + if err != nil { + return nil, err + } ingressRouteUDPEndpoints, err := ts.ingressRouteUDPEndpoints() if err != nil { return nil, err } + oldIngressRouteUDPEndpoints, err := ts.oldIngressRouteUDPEndpoints() + if err != nil { + return nil, err + } endpoints = append(endpoints, ingressRouteEndpoints...) endpoints = append(endpoints, ingressRouteTCPEndpoints...) endpoints = append(endpoints, ingressRouteUDPEndpoints...) + endpoints = append(endpoints, oldIngressRouteEndpoints...) + endpoints = append(endpoints, oldIngressRouteTCPEndpoints...) + endpoints = append(endpoints, oldIngressRouteUDPEndpoints...) for _, ep := range endpoints { sort.Sort(ep.Targets) @@ -312,6 +366,168 @@ func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error return endpoints, nil } +// oldIngressRouteEndpoints extracts endpoints from all IngressRoute objects +func (ts *traefikSource) oldIngressRouteEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.oldIngressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRoutes []*IngressRoute + for _, ingressRouteObj := range irs { + unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert IngressRoute object to unstructured") + } + + ingressRoute := &IngressRoute{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + if err != nil { + return nil, err + } + ingressRoutes = append(ingressRoutes, ingressRoute) + } + + ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRoute") + } + + for _, ingressRoute := range ingressRoutes { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRoute(ingressRoute, ingressEndpoints) + ts.setDualstackLabelIngressRoute(ingressRoute, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} + +// oldIngressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects +func (ts *traefikSource) oldIngressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.oldIngressRouteTcpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRouteTCPs []*IngressRouteTCP + for _, ingressRouteTCPObj := range irs { + unstructuredHost, ok := ingressRouteTCPObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert IngressRouteTCP object to unstructured") + } + + ingressRouteTCP := &IngressRouteTCP{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRouteTCP, nil) + if err != nil { + return nil, err + } + ingressRouteTCPs = append(ingressRouteTCPs, ingressRouteTCP) + } + + ingressRouteTCPs, err = ts.filterIngressRouteTcpByAnnotations(ingressRouteTCPs) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRouteTCP") + } + + for _, ingressRouteTCP := range ingressRouteTCPs { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteTCP.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints) + ts.setDualstackLabelIngressRouteTCP(ingressRouteTCP, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} + +// oldIngressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects +func (ts *traefikSource) oldIngressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + irs, err := ts.oldIngressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything()) + if err != nil { + return nil, err + } + + var ingressRouteUDPs []*IngressRouteUDP + for _, ingressRouteUDPObj := range irs { + unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured) + if !ok { + return nil, errors.New("could not convert IngressRouteUDP object to unstructured") + } + + ingressRoute := &IngressRouteUDP{} + err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil) + if err != nil { + return nil, err + } + ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute) + } + + ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs) + if err != nil { + return nil, errors.Wrap(err, "failed to filter IngressRouteUDP") + } + + for _, ingressRouteUDP := range ingressRouteUDPs { + var targets endpoint.Targets + + targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...) + + fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name) + + ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets) + if err != nil { + return nil, err + } + if len(ingressEndpoints) == 0 { + log.Debugf("No endpoints could be generated from Host %s", fullname) + continue + } + + log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints) + ts.setResourceLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints) + ts.setDualstackLabelIngressRouteUDP(ingressRouteUDP, ingressEndpoints) + endpoints = append(endpoints, ingressEndpoints...) + } + + return endpoints, nil +} + // filterIngressRouteByAnnotation filters a list of IngressRoute by a given annotation selector. func (ts *traefikSource) filterIngressRouteByAnnotation(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) { labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter) @@ -544,10 +760,13 @@ func (ts *traefikSource) AddEventHandler(ctx context.Context, handler func()) { // https://github.com/kubernetes/kubernetes/issues/79610 log.Debug("Adding event handler for IngressRoute") ts.ingressRouteInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + ts.oldIngressRouteInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) log.Debug("Adding event handler for IngressRouteTCP") ts.ingressRouteTcpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + ts.oldIngressRouteTcpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) log.Debug("Adding event handler for IngressRouteUDP") ts.ingressRouteUdpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) + ts.oldIngressRouteUdpInformer.Informer().AddEventHandler(eventHandlerFunc(handler)) } // newTraefikUnstructuredConverter returns a new unstructuredConverter initialized @@ -558,8 +777,11 @@ func newTraefikUnstructuredConverter() (*unstructuredConverter, error) { // Add the core types we need uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + uc.scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + uc.scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + uc.scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) if err := scheme.AddToScheme(uc.scheme); err != nil { return nil, err } diff --git a/source/traefik_proxy_test.go b/source/traefik_proxy_test.go index 43bc30e56a..eb26ed2b31 100644 --- a/source/traefik_proxy_test.go +++ b/source/traefik_proxy_test.go @@ -283,6 +283,9 @@ func TestTraefikProxyIngressRouteEndpoints(t *testing.T) { scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} @@ -525,6 +528,9 @@ func TestTraefikProxyIngressRouteTCPEndpoints(t *testing.T) { scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} @@ -643,6 +649,9 @@ func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) ir := unstructured.Unstructured{} @@ -672,3 +681,650 @@ func TestTraefikProxyIngressRouteUDPEndpoints(t *testing.T) { }) } } + +func TestTraefikProxyOldIngressRouteEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRoute IngressRoute + expected []*endpoint.Endpoint + }{ + { + title: "IngressRoute with hostname annotation", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with host rule", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ + { + Match: "Host(`b.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with hostheader rule", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-hostheader-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ + { + Match: "HostHeader(`c.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "c.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-hostheader-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with multiple host rules", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-multi-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ + { + Match: "Host(`d.example.com`) || Host(`e.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "d.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "e.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute with multiple host rules and annotation", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-multi-host-annotations-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "f.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ + { + Match: "Host(`g.example.com`, `h.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "f.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "g.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "h.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroute/traefik/ingressroute-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRoute omit wildcard", + ingressRoute: IngressRoute{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteGVR.GroupVersion().String(), + Kind: "IngressRoute", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroute-omit-wildcard-host", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteSpec{ + Routes: []traefikRoute{ + { + Match: "Host(`*`)", + }, + }, + }, + }, + expected: nil, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRoute) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(oldIngressrouteGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(oldIngressrouteGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} + +func TestTraefikProxyOldIngressRouteTCPEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRouteTCP IngressRouteTCP + expected []*endpoint.Endpoint + }{ + { + title: "IngressRouteTCP with hostname annotation", + ingressRouteTCP: IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteTCPGVR.GroupVersion().String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with host sni rule", + ingressRouteTCP: IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteTCPGVR.GroupVersion().String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-hostsni-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ + { + Match: "HostSNI(`b.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-hostsni-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple host sni rules", + ingressRouteTCP: IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteTCPGVR.GroupVersion().String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-multi-host-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ + { + Match: "HostSNI(`d.example.com`) || HostSNI(`e.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "d.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "e.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple host sni rules and annotation", + ingressRouteTCP: IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteTCPGVR.GroupVersion().String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-multi-host-annotations-match", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "f.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ + { + Match: "HostSNI(`g.example.com`, `h.example.com`)", + }, + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "f.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "g.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "h.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressroutetcp/traefik/ingressroutetcp-multi-host-annotations-match", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP omit wildcard host sni", + ingressRouteTCP: IngressRouteTCP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteTCPGVR.GroupVersion().String(), + Kind: "IngressRouteTCP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressroutetcp-omit-wildcard-host", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + Spec: traefikIngressRouteTCPSpec{ + Routes: []traefikRouteTCP{ + { + Match: "HostSNI(`*`)", + }, + }, + }, + }, + expected: nil, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRouteTCP) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(oldIngressrouteTCPGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(oldIngressrouteTCPGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} + +func TestTraefikProxyOldIngressRouteUDPEndpoints(t *testing.T) { + t.Parallel() + + for _, ti := range []struct { + title string + ingressRouteUDP IngressRouteUDP + expected []*endpoint.Endpoint + }{ + { + title: "IngressRouteTCP with hostname annotation", + ingressRouteUDP: IngressRouteUDP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteUDPGVR.GroupVersion().String(), + Kind: "IngressRouteUDP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressrouteudp-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + { + title: "IngressRouteTCP with multiple hostname annotation", + ingressRouteUDP: IngressRouteUDP{ + TypeMeta: metav1.TypeMeta{ + APIVersion: oldIngressrouteUDPGVR.GroupVersion().String(), + Kind: "IngressRouteUDP", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "ingressrouteudp-multi-annotation", + Namespace: defaultTraefikNamespace, + Annotations: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "a.example.com, b.example.com", + "external-dns.alpha.kubernetes.io/target": "target.domain.tld", + "kubernetes.io/ingress.class": "traefik", + }, + }, + }, + expected: []*endpoint.Endpoint{ + { + DNSName: "a.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-multi-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + { + DNSName: "b.example.com", + Targets: []string{"target.domain.tld"}, + RecordType: endpoint.RecordTypeCNAME, + RecordTTL: 0, + Labels: endpoint.Labels{ + "resource": "ingressrouteudp/traefik/ingressrouteudp-multi-annotation", + }, + ProviderSpecific: endpoint.ProviderSpecific{}, + }, + }, + }, + } { + ti := ti + t.Run(ti.title, func(t *testing.T) { + t.Parallel() + + fakeKubernetesClient := fakeKube.NewSimpleClientset() + scheme := runtime.NewScheme() + scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{}) + scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{}) + scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{}) + fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) + + ir := unstructured.Unstructured{} + + ingressRouteAsJSON, err := json.Marshal(ti.ingressRouteUDP) + assert.NoError(t, err) + + assert.NoError(t, ir.UnmarshalJSON(ingressRouteAsJSON)) + + // Create proxy resources + _, err = fakeDynamicClient.Resource(oldIngressrouteUDPGVR).Namespace(defaultTraefikNamespace).Create(context.Background(), &ir, metav1.CreateOptions{}) + assert.NoError(t, err) + + source, err := NewTraefikSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultTraefikNamespace, "kubernetes.io/ingress.class=traefik") + assert.NoError(t, err) + assert.NotNil(t, source) + + count := &unstructured.UnstructuredList{} + for len(count.Items) < 1 { + count, _ = fakeDynamicClient.Resource(oldIngressrouteUDPGVR).Namespace(defaultTraefikNamespace).List(context.Background(), metav1.ListOptions{}) + } + + endpoints, err := source.Endpoints(context.Background()) + assert.NoError(t, err) + assert.Len(t, endpoints, len(ti.expected)) + assert.Equal(t, endpoints, ti.expected) + }) + } +} From 9105dc020b20602b4ebad3e8a7c241c2fd50b16e Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 14 Jun 2023 18:27:39 +0200 Subject: [PATCH 109/154] Added missing GVKs for store tests Signed-off-by: Thomas Kosiewski --- source/store_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/store_test.go b/source/store_test.go index 773475b69e..adb70633dd 100644 --- a/source/store_test.go +++ b/source/store_test.go @@ -145,6 +145,21 @@ func (suite *ByNamesTestSuite) TestAllInitialized() { Version: "v1alpha1", Resource: "ingressrouteudps", }: "IngressRouteUDPList", + { + Group: "traefik.io", + Version: "v1alpha1", + Resource: "ingressroutes", + }: "IngressRouteList", + { + Group: "traefik.io", + Version: "v1alpha1", + Resource: "ingressroutetcps", + }: "IngressRouteTCPList", + { + Group: "traefik.io", + Version: "v1alpha1", + Resource: "ingressrouteudps", + }: "IngressRouteUDPList", }), nil) sources, err := ByNames(context.TODO(), mockClientGenerator, []string{"service", "ingress", "istio-gateway", "contour-httpproxy", "kong-tcpingress", "f5-virtualserver", "traefik-proxy", "fake"}, minimalConfig) From 3056ac57d690c78a0c2ca8402805894aaf8c53d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20J=2E=20Nu=C3=B1ez=20Madrazo?= Date: Wed, 14 Jun 2023 23:42:40 +0100 Subject: [PATCH 110/154] Fix bug in the civo provider to avoid infinite record creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro J. Nuñez Madrazo --- docs/tutorials/civo.md | 5 +- go.mod | 45 ++++++----- go.sum | 152 +++++++++++++++++++++---------------- provider/civo/civo.go | 10 +++ provider/civo/civo_test.go | 148 ++++++++++++++++++++++++++++++++++++ 5 files changed, 269 insertions(+), 91 deletions(-) diff --git a/docs/tutorials/civo.md b/docs/tutorials/civo.md index 32166a1e89..7da6cbce07 100644 --- a/docs/tutorials/civo.md +++ b/docs/tutorials/civo.md @@ -2,7 +2,7 @@ This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using Civo DNS Manager. -Make sure to use **>0.12.2** version of ExternalDNS for this tutorial. +Make sure to use **>0.13.5** version of ExternalDNS for this tutorial. ## Managing DNS with Civo @@ -12,8 +12,7 @@ If you want to learn about how to use Civo DNS Manager read the following tutori ## Get Civo Token -Copy the token in the settings fo your account - +Copy the token in the settings for your account The environment variable `CIVO_TOKEN` will be needed to run ExternalDNS with Civo. ## Deploy ExternalDNS diff --git a/go.mod b/go.mod index 227ccc6081..fb51f57184 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/ans-group/sdk-go v1.10.4 github.com/aws/aws-sdk-go v1.44.136 github.com/bodgit/tsig v1.2.2 - github.com/civo/civogo v0.3.14 + github.com/civo/civogo v0.3.37 github.com/cloudflare/cloudflare-go v0.58.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 github.com/datawire/ambassador v1.6.0 @@ -61,7 +61,7 @@ require ( go.etcd.io/etcd/api/v3 v3.5.8 go.etcd.io/etcd/client/v3 v3.5.8 go.uber.org/ratelimit v0.2.0 - golang.org/x/net v0.8.0 + golang.org/x/net v0.11.0 golang.org/x/oauth2 v0.5.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.110.0 @@ -69,8 +69,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 istio.io/api v0.0.0-20210128181506-0c4b8e54850f istio.io/client-go v0.0.0-20210128182905-ee2edd059e02 - k8s.io/api v0.26.0 - k8s.io/apimachinery v0.26.0 + k8s.io/api v0.27.1 + k8s.io/apimachinery v0.27.1 k8s.io/client-go v0.26.0 sigs.k8s.io/gateway-api v0.6.0 ) @@ -105,21 +105,20 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/strfmt v0.21.5 // indirect - github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.13.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect - github.com/go-stack/stack v1.8.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -143,7 +142,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.3 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect @@ -177,13 +176,13 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect google.golang.org/grpc v1.53.0 // indirect @@ -195,14 +194,18 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect moul.io/http2curl v1.0.0 // indirect sigs.k8s.io/controller-runtime v0.12.1 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) -replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a +replace ( + k8s.io/api => k8s.io/api v0.26.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.0 + k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a +) diff --git a/go.sum b/go.sum index ae19339555..57cd6bfae3 100644 --- a/go.sum +++ b/go.sum @@ -86,7 +86,6 @@ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 h1:/ZCtF9JC9VyTN2bdwtHnlpCoJOWxZ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1/go.mod h1:vdlVHq8oUD8W8yUr53RSZ9hKkOcboFcgvhS6nMKH+qc= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= -github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= @@ -162,12 +161,12 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -192,8 +191,6 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+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/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= -github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= github.com/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -212,8 +209,8 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/civo/civogo v0.3.14 h1:W+o+hFXtEhWyJOmZOm2C5s8OEorSXGP6eyPYOa69NA8= -github.com/civo/civogo v0.3.14/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak= +github.com/civo/civogo v0.3.37 h1:iNFsmv5PrfWy0J7JLw0sS0LhNaaR66m5aVRB3cvYSsA= +github.com/civo/civogo v0.3.37/go.mod h1:ovGwXtszFiTsVq1OgKG9CtE8q8TPm+4bwE13KuJBr9E= 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/cloudflare/cloudflare-go v0.58.1 h1:+Tqt4N9nuNEMgSC3tCQOixyifU5jihaq+JfDQidTSgY= @@ -296,7 +293,6 @@ github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw 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= @@ -310,6 +306,7 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB 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.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= @@ -384,7 +381,6 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 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/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= @@ -394,15 +390,16 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds 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.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.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.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/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= @@ -421,7 +418,6 @@ github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pL 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/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlONADE= github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= @@ -430,19 +426,18 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ 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.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= @@ -455,8 +450,8 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr 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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= @@ -548,8 +543,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/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/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= @@ -571,6 +567,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -589,6 +586,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= @@ -609,8 +607,6 @@ github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1a github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 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/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= -github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= github.com/gophercloud/gophercloud v1.4.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -667,7 +663,6 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX 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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -704,19 +699,14 @@ github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFK github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE/Tq8= github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -782,7 +772,6 @@ github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= @@ -816,8 +805,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN 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.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -853,7 +842,6 @@ github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08 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/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c= @@ -932,7 +920,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv 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.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= 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= @@ -944,7 +941,17 @@ github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4 github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= 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= @@ -1217,6 +1224,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/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.1/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= @@ -1236,7 +1244,6 @@ go.etcd.io/etcd/client/v3 v3.5.8/go.mod h1:idZYIPVkttBJBiRigkB5EM0MmEyx8jcl18zCV 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.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= @@ -1291,22 +1298,19 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh 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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1340,11 +1344,13 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1398,17 +1404,23 @@ golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= 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= @@ -1511,10 +1523,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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= @@ -1522,18 +1537,24 @@ golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1545,10 +1566,12 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.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= @@ -1628,11 +1651,14 @@ golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1737,6 +1763,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -1813,13 +1840,6 @@ istio.io/client-go v0.0.0-20210128182905-ee2edd059e02/go.mod h1:oXMjFUWhxlReUSbg istio.io/gogo-genproto v0.0.0-20190904133402-ee07f2785480/go.mod h1:uKtbae4K9k2rjjX4ToV0l6etglbc1i7gqQ94XdkshzY= istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE= istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs= -k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= -k8s.io/api v0.18.1/go.mod h1:3My4jorQWzSs5a+l7Ge6JBbIxChLnY8HnuT58ZWolss= -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.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= -k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= k8s.io/api v0.26.0 h1:IpPlZnxBpV1xl7TGk/X6lFtpgjgntCg8PJ+qrPHAC7I= k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo= @@ -1827,13 +1847,6 @@ k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJ k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= k8s.io/apiextensions-apiserver v0.20.4/go.mod h1:Hzebis/9c6Io5yzHp24Vg4XOkTp1ViMwKP/6gmpsfA4= k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= -k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.18.1/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.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw= @@ -1868,6 +1881,7 @@ k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 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= @@ -1876,16 +1890,19 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= 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-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= +k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1901,8 +1918,9 @@ sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXe sigs.k8s.io/controller-tools v0.3.1-0.20200517180335-820a4a27ea84/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +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= diff --git a/provider/civo/civo.go b/provider/civo/civo.go index bd61bd98e1..17d49096ba 100644 --- a/provider/civo/civo.go +++ b/provider/civo/civo.go @@ -46,6 +46,11 @@ type CivoChanges struct { Updates []*CivoChangeUpdate } +// Empty returns true if there are no changes +func (c *CivoChanges) Empty() bool { + return len(c.Creates) == 0 && len(c.Updates) == 0 && len(c.Deletes) == 0 +} + // CivoChangeCreate Civo Domain Record Creates type CivoChangeCreate struct { Domain civogo.DNSDomain @@ -169,6 +174,11 @@ func (p *CivoProvider) fetchZones(ctx context.Context) ([]civogo.DNSDomain, erro // submitChanges takes a zone and a collection of Changes and sends them as a single transaction. func (p *CivoProvider) submitChanges(ctx context.Context, changes CivoChanges) error { + if changes.Empty() { + log.Info("All records are already up to date") + return nil + } + for _, change := range changes.Creates { logFields := log.Fields{ "Type": change.Options.Type, diff --git a/provider/civo/civo_test.go b/provider/civo/civo_test.go index 6d637d0774..6a05a7d8fb 100644 --- a/provider/civo/civo_test.go +++ b/provider/civo/civo_test.go @@ -809,6 +809,154 @@ func TestCivo_submitChangesDelete(t *testing.T) { assert.NoError(t, err) } +func TestCivoChangesEmpty(t *testing.T) { + // Test empty CivoChanges + c := &CivoChanges{} + assert.True(t, c.Empty()) + + // Test CivoChanges with Creates + c = &CivoChanges{ + Creates: []*CivoChangeCreate{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + Options: &civogo.DNSRecordConfig{ + Type: civogo.DNSRecordTypeA, + Name: "www", + Value: "192.1.1.1", + Priority: 0, + TTL: 600, + }, + }, + }, + } + assert.False(t, c.Empty()) + + // Test CivoChanges with Updates + c = &CivoChanges{ + Updates: []*CivoChangeUpdate{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + DomainRecord: civogo.DNSRecord{ + ID: "76cc107f-fbef-4e2b-b97f-f5d34f4075d3", + AccountID: "1", + DNSDomainID: "12345", + Name: "mail", + Value: "192.168.1.2", + Type: "MX", + Priority: 10, + TTL: 600, + }, + Options: civogo.DNSRecordConfig{ + Type: "MX", + Name: "mail", + Value: "192.168.1.3", + Priority: 10, + TTL: 600, + }, + }, + }, + } + assert.False(t, c.Empty()) + + // Test CivoChanges with Deletes + c = &CivoChanges{ + Deletes: []*CivoChangeDelete{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + DomainRecord: civogo.DNSRecord{ + ID: "76cc107f-fbef-4e2b-b97f-f5d34f4075d3", + AccountID: "1", + DNSDomainID: "12345", + Name: "mail", + Value: "192.168.1.3", + Type: "MX", + Priority: 10, + TTL: 600, + }, + }, + }, + } + assert.False(t, c.Empty()) + + // Test CivoChanges with Creates, Updates, and Deletes + c = &CivoChanges{ + Creates: []*CivoChangeCreate{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + Options: &civogo.DNSRecordConfig{ + Type: civogo.DNSRecordTypeA, + Name: "www", + Value: "192.1.1.1", + Priority: 0, + TTL: 600, + }, + }, + }, + Updates: []*CivoChangeUpdate{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + DomainRecord: civogo.DNSRecord{ + ID: "76cc107f-fbef-4e2b-b97f-f5d34f4075d3", + AccountID: "1", + DNSDomainID: "12345", + Name: "mail", + Value: "192.168.1.2", + Type: "MX", + Priority: 10, + TTL: 600, + }, + Options: civogo.DNSRecordConfig{ + Type: "MX", + Name: "mail", + Value: "192.168.1.3", + Priority: 10, + TTL: 600, + }, + }, + }, + Deletes: []*CivoChangeDelete{ + { + Domain: civogo.DNSDomain{ + ID: "12345", + AccountID: "1", + Name: "example.com", + }, + DomainRecord: civogo.DNSRecord{ + ID: "76cc107f-fbef-4e2b-b97f-f5d34f4075d3", + AccountID: "1", + DNSDomainID: "12345", + Name: "mail", + Value: "192.168.1.3", + Type: "MX", + Priority: 10, + TTL: 600, + }, + }, + }, + } + assert.False(t, c.Empty()) +} + // This function is an adapted copy of the testify package's ElementsMatch function with the // call to ObjectsAreEqual replaced with cmp.Equal which better handles struct's with pointers to // other structs. It also ignores ordering when comparing unlike cmp.Equal. From aa2bb4d974a63c275012a7ea2f8dac8fe70de11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20J=2E=20Nu=C3=B1ez=20Madrazo?= Date: Wed, 14 Jun 2023 23:51:30 +0100 Subject: [PATCH 111/154] Fix file with gofmt lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro J. Nuñez Madrazo --- provider/civo/civo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/civo/civo.go b/provider/civo/civo.go index 17d49096ba..3f6dd9e0e2 100644 --- a/provider/civo/civo.go +++ b/provider/civo/civo.go @@ -178,7 +178,7 @@ func (p *CivoProvider) submitChanges(ctx context.Context, changes CivoChanges) e log.Info("All records are already up to date") return nil } - + for _, change := range changes.Creates { logFields := log.Fields{ "Type": change.Options.Type, From 88a726f690fe628c2164a62e1175d0e928e42b18 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 15 Jun 2023 09:04:52 +0200 Subject: [PATCH 112/154] Update docs/tutorials/traefik-proxy.md Co-authored-by: Michel Loiseleur <97035654+mloiseleur@users.noreply.github.com> --- docs/tutorials/traefik-proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/traefik-proxy.md b/docs/tutorials/traefik-proxy.md index 325d7a1d60..1e756f73ab 100644 --- a/docs/tutorials/traefik-proxy.md +++ b/docs/tutorials/traefik-proxy.md @@ -51,7 +51,7 @@ rules: - apiGroups: [""] resources: ["nodes"] verbs: ["list","watch"] -- apiGroups: ["traefik.containo.us"] +- apiGroups: ["traefik.containo.us","traefik.io"] resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps"] verbs: ["get","watch","list"] --- From 97deda58ef781fb32ed280f065df4e2b3db1abc9 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 15 Jun 2023 10:50:30 +0200 Subject: [PATCH 113/154] Updated traefik docs to use registry.k8s.io Signed-off-by: Thomas Kosiewski --- docs/tutorials/traefik-proxy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/traefik-proxy.md b/docs/tutorials/traefik-proxy.md index 1e756f73ab..7b83a1a7c9 100644 --- a/docs/tutorials/traefik-proxy.md +++ b/docs/tutorials/traefik-proxy.md @@ -24,7 +24,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: k8s.gcr.io/external-dns/external-dns:v0.13.3 + image: registry.k8s.io/external-dns/external-dns:v0.13.3 args: - --source=traefik-proxy - --provider=aws @@ -87,7 +87,7 @@ spec: containers: - name: external-dns # update this to the desired external-dns version - image: k8s.gcr.io/external-dns/external-dns:v0.13.3 + image: registry.k8s.io/external-dns/external-dns:v0.13.3 args: - --source=traefik-proxy - --provider=aws From 1bd38347430ac0dddd8e68e23ecf12c426369892 Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 25 May 2023 11:04:17 +0200 Subject: [PATCH 114/154] handle missing TXT records with a forcedUpdate strategy This change tries to remove part of the logic added in 50f196c0db280de7a9b55a8f7fd6b0a607ac5472. The forceUpdate strategy relies on existing code of the planner to migrate TXT records to the new format, being the main goal to avoid conflicts during apply. Signed-off-by: Matias Charriere --- controller/controller.go | 25 ------------------------- endpoint/endpoint.go | 13 ++++++++----- plan/plan.go | 9 +-------- registry/registry.go | 1 - registry/txt.go | 20 +------------------- 5 files changed, 10 insertions(+), 58 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 0012ac0887..af3e3219a2 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -195,8 +195,6 @@ func (c *Controller) RunOnce(ctx context.Context) error { return err } - missingRecords := c.Registry.MissingRecords() - registryEndpointsTotal.Set(float64(len(records))) regARecords, regAAAARecords := countAddressRecords(records) registryARecords.Set(float64(regARecords)) @@ -218,29 +216,6 @@ func (c *Controller) RunOnce(ctx context.Context) error { verifiedAAAARecords.Set(float64(vAAAARecords)) endpoints = c.Registry.AdjustEndpoints(endpoints) - if len(missingRecords) > 0 { - // Add missing records before the actual plan is applied. - // This prevents the problems when the missing TXT record needs to be - // created and deleted/upserted in the same batch. - missingRecordsPlan := &plan.Plan{ - Policies: []plan.Policy{c.Policy}, - Missing: missingRecords, - DomainFilter: endpoint.MatchAllDomainFilters{c.DomainFilter, c.Registry.GetDomainFilter()}, - PropertyComparator: c.Registry.PropertyValuesEqual, - ManagedRecords: c.ManagedRecordTypes, - } - missingRecordsPlan = missingRecordsPlan.Calculate() - if missingRecordsPlan.Changes.HasChanges() { - err = c.Registry.ApplyChanges(ctx, missingRecordsPlan.Changes) - if err != nil { - registryErrorsTotal.Inc() - deprecatedRegistryErrors.Inc() - return err - } - log.Info("All missing records are created") - } - } - plan := &plan.Plan{ Policies: []plan.Policy{c.Policy}, Current: records, diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 736f1e5740..46370fe5e1 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -170,6 +170,8 @@ type Endpoint struct { Targets Targets `json:"targets,omitempty"` // RecordType type of record, e.g. CNAME, A, AAAA, SRV, TXT etc RecordType string `json:"recordType,omitempty"` + // Force planner to update record + ForceUpdate bool `json:"forceUpdate,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 @@ -202,11 +204,12 @@ func NewEndpointWithTTL(dnsName, recordType string, ttl TTL, targets ...string) } return &Endpoint{ - DNSName: strings.TrimSuffix(dnsName, "."), - Targets: cleanTargets, - RecordType: recordType, - Labels: NewLabels(), - RecordTTL: ttl, + DNSName: strings.TrimSuffix(dnsName, "."), + Targets: cleanTargets, + RecordType: recordType, + ForceUpdate: false, + Labels: NewLabels(), + RecordTTL: ttl, } } diff --git a/plan/plan.go b/plan/plan.go index 1e8a38f1e1..e9aab6fb71 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -37,8 +37,6 @@ type Plan struct { Current []*endpoint.Endpoint // List of desired records Desired []*endpoint.Endpoint - // List of missing records to be created, use for the migrations (e.g. old-new TXT format) - Missing []*endpoint.Endpoint // Policies under which the desired changes are calculated Policies []Policy // List of changes necessary to move towards desired state @@ -165,7 +163,7 @@ func (p *Plan) Calculate() *Plan { if row.current != nil && len(row.candidates) > 0 { // dns name is taken update := t.resolver.ResolveUpdate(row.current, row.candidates) // compare "update" to "current" to figure out if actual update is required - if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) { + if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) || row.current.ForceUpdate { inheritOwner(row.current, update) changes.UpdateNew = append(changes.UpdateNew, update) changes.UpdateOld = append(changes.UpdateOld, row.current) @@ -177,11 +175,6 @@ func (p *Plan) Calculate() *Plan { changes = pol.Apply(changes) } - // Handle the migration of the TXT records created before the new format (introduced in v0.12.0) - if len(p.Missing) > 0 { - changes.Create = append(changes.Create, filterRecordsForPlan(p.Missing, p.DomainFilter, append(p.ManagedRecords, endpoint.RecordTypeTXT))...) - } - plan := &Plan{ Current: p.Current, Desired: p.Desired, diff --git a/registry/registry.go b/registry/registry.go index 7f219a8463..fa39fb8ec0 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -35,7 +35,6 @@ type Registry interface { PropertyValuesEqual(attribute string, previous string, current string) bool AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint GetDomainFilter() endpoint.DomainFilterInterface - MissingRecords() []*endpoint.Endpoint } // TODO(ideahitme): consider moving this to Plan diff --git a/registry/txt.go b/registry/txt.go index 2c7cccbdf2..e00136cc9e 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -50,9 +50,6 @@ type TXTRegistry struct { managedRecordTypes []string - // missingTXTRecords stores TXT records which are missing after the migration to the new format - missingTXTRecords []*endpoint.Endpoint - // encrypt text records txtEncryptEnabled bool txtEncryptAESKey []byte @@ -117,7 +114,6 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error } endpoints := []*endpoint.Endpoint{} - missingEndpoints := []*endpoint.Endpoint{} labelMap := map[string]endpoint.Labels{} txtRecordsMap := map[string]struct{}{} @@ -174,17 +170,11 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error if plan.IsManagedRecord(ep.RecordType, im.managedRecordTypes) { // Get desired TXT records and detect the missing ones desiredTXTs := im.generateTXTRecord(ep) - missingDesiredTXTs := []*endpoint.Endpoint{} for _, desiredTXT := range desiredTXTs { if _, exists := txtRecordsMap[desiredTXT.DNSName]; !exists { - missingDesiredTXTs = append(missingDesiredTXTs, desiredTXT) + ep.ForceUpdate = true } } - if len(desiredTXTs) > len(missingDesiredTXTs) { - // Add missing TXT records only if those are managed (by externaldns) ones. - // The unmanaged record has both of the desired TXT records missing. - missingEndpoints = append(missingEndpoints, missingDesiredTXTs...) - } } } } @@ -195,17 +185,9 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error im.recordsCacheRefreshTime = time.Now() } - im.missingTXTRecords = missingEndpoints - return endpoints, nil } -// MissingRecords returns the TXT record to be created. -// The missing records are collected during the run of Records method. -func (im *TXTRegistry) MissingRecords() []*endpoint.Endpoint { - return im.missingTXTRecords -} - // generateTXTRecord generates both "old" and "new" TXT records. // Once we decide to drop old format we need to drop toTXTName() and rename toNewTXTName func (im *TXTRegistry) generateTXTRecord(r *endpoint.Endpoint) []*endpoint.Endpoint { From e938f5a67fe47426326fcdc0523a72e171d95334 Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 25 May 2023 21:45:19 +0200 Subject: [PATCH 115/154] remove tests from missing endpoint tests from controller the entire logic of missing endpoints was removed from the controller taking leverage on the planner Signed-off-by: Matias Charriere --- controller/controller_test.go | 99 ----------------------------------- 1 file changed, 99 deletions(-) diff --git a/controller/controller_test.go b/controller/controller_test.go index f6b03d4331..9f37ab2952 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -311,51 +311,6 @@ func testControllerFiltersDomains(t *testing.T, configuredEndpoints []*endpoint. } } -type noopRegistryWithMissing struct { - *registry.NoopRegistry - missingRecords []*endpoint.Endpoint -} - -func (r *noopRegistryWithMissing) MissingRecords() []*endpoint.Endpoint { - return r.missingRecords -} - -func testControllerFiltersDomainsWithMissing(t *testing.T, configuredEndpoints []*endpoint.Endpoint, domainFilter endpoint.DomainFilterInterface, providerEndpoints, missingEndpoints []*endpoint.Endpoint, expectedChanges []*plan.Changes) { - t.Helper() - cfg := externaldns.NewConfig() - cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME} - - source := new(testutils.MockSource) - source.On("Endpoints").Return(configuredEndpoints, nil) - - // Fake some existing records in our DNS provider and validate some desired changes. - provider := &filteredMockProvider{ - RecordsStore: providerEndpoints, - } - noop, err := registry.NewNoopRegistry(provider) - require.NoError(t, err) - - r := &noopRegistryWithMissing{ - NoopRegistry: noop, - missingRecords: missingEndpoints, - } - - ctrl := &Controller{ - Source: source, - Registry: r, - Policy: &plan.SyncPolicy{}, - DomainFilter: domainFilter, - ManagedRecordTypes: cfg.ManagedDNSRecordTypes, - } - - assert.NoError(t, ctrl.RunOnce(context.Background())) - assert.Equal(t, 1, provider.RecordsCallCount) - require.Len(t, provider.ApplyChangesCalls, len(expectedChanges)) - for i, change := range expectedChanges { - assert.Equal(t, *change, *provider.ApplyChangesCalls[i]) - } -} - func TestControllerSkipsEmptyChanges(t *testing.T) { testControllerFiltersDomains( t, @@ -683,60 +638,6 @@ func TestARecords(t *testing.T) { assert.Equal(t, math.Float64bits(1), valueFromMetric(registryARecords)) } -// TestMissingRecordsApply validates that the missing records result in the dedicated plan apply. -func TestMissingRecordsApply(t *testing.T) { - testControllerFiltersDomainsWithMissing( - t, - []*endpoint.Endpoint{ - { - DNSName: "record1.used.tld", - RecordType: endpoint.RecordTypeA, - Targets: endpoint.Targets{"1.2.3.4"}, - }, - { - DNSName: "record2.used.tld", - RecordType: endpoint.RecordTypeA, - Targets: endpoint.Targets{"8.8.8.8"}, - }, - }, - endpoint.NewDomainFilter([]string{"used.tld"}), - []*endpoint.Endpoint{ - { - DNSName: "record1.used.tld", - RecordType: endpoint.RecordTypeA, - Targets: endpoint.Targets{"1.2.3.4"}, - }, - }, - []*endpoint.Endpoint{ - { - DNSName: "a-record1.used.tld", - RecordType: endpoint.RecordTypeTXT, - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - }, - }, - []*plan.Changes{ - // Missing record had its own plan applied. - { - Create: []*endpoint.Endpoint{ - { - DNSName: "a-record1.used.tld", - RecordType: endpoint.RecordTypeTXT, - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - }, - }, - }, - { - Create: []*endpoint.Endpoint{ - { - DNSName: "record2.used.tld", - RecordType: endpoint.RecordTypeA, - Targets: endpoint.Targets{"8.8.8.8"}, - }, - }, - }, - }) -} - func TestAAAARecords(t *testing.T) { testControllerFiltersDomains( t, From a0e291b46b426d2b1679388b1826872b1a90a252 Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 25 May 2023 21:48:58 +0200 Subject: [PATCH 116/154] update registry tests to match new strategy Signed-off-by: Matias Charriere --- internal/testutils/endpoint.go | 3 +- registry/aws_sd_registry.go | 5 -- registry/noop.go | 5 -- registry/txt_test.go | 149 +++++++++++++-------------------- 4 files changed, 62 insertions(+), 100 deletions(-) diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index f8b4657958..fe13fb9346 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -63,7 +63,8 @@ func SameEndpoint(a, b *endpoint.Endpoint) bool { a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL && a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] && a.Labels[endpoint.OwnedRecordLabelKey] == b.Labels[endpoint.OwnedRecordLabelKey] && - SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific) + SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific) && + a.ForceUpdate == b.ForceUpdate } // SameEndpoints compares two slices of endpoints regardless of order diff --git a/registry/aws_sd_registry.go b/registry/aws_sd_registry.go index f0fef584d9..1ecd885463 100644 --- a/registry/aws_sd_registry.go +++ b/registry/aws_sd_registry.go @@ -67,11 +67,6 @@ func (sdr *AWSSDRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, er return records, nil } -// MissingRecords returns nil because there is no missing records for AWSSD registry -func (sdr *AWSSDRegistry) MissingRecords() []*endpoint.Endpoint { - return nil -} - // ApplyChanges filters out records not owned the External-DNS, additionally it adds the required label // inserted in the AWS SD instance as a CreateID field func (sdr *AWSSDRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) error { diff --git a/registry/noop.go b/registry/noop.go index d48cd82fe0..73257730cd 100644 --- a/registry/noop.go +++ b/registry/noop.go @@ -45,11 +45,6 @@ func (im *NoopRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, erro return im.provider.Records(ctx) } -// MissingRecords returns nil because there is no missing records for Noop registry -func (im *NoopRegistry) MissingRecords() []*endpoint.Endpoint { - return nil -} - // ApplyChanges propagates changes to the dns provider func (im *NoopRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) error { return im.provider.ApplyChanges(ctx, changes) diff --git a/registry/txt_test.go b/registry/txt_test.go index 80075c81d1..0e1fe3c83c 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -868,95 +868,81 @@ func testTXTRegistryMissingRecordsNoPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + ForceUpdate: true, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: true, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, + ForceUpdate: false, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, // Only TXT records with the wrong heritage are returned by Records() { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, + ForceUpdate: false, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: false, Labels: map[string]string{ // Records() retrieves all the records of the zone, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: false, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + ForceUpdate: false, }, { - DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, + DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + ForceUpdate: false, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, } - expectedMissingRecords := []*endpoint.Endpoint{ - { - DNSName: "cname-oldformat.test-zone.example.org", - // owner is taken from the source record (A, CNAME, etc.) - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: endpoint.RecordTypeTXT, - Labels: endpoint.Labels{ - endpoint.OwnedRecordLabelKey: "oldformat.test-zone.example.org", - }, - }, - { - DNSName: "a-oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: endpoint.RecordTypeTXT, - Labels: endpoint.Labels{ - endpoint.OwnedRecordLabelKey: "oldformat2.test-zone.example.org", - }, - }, - } - r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) records, _ := r.Records(ctx) - missingRecords := r.MissingRecords() assert.True(t, testutils.SameEndpoints(records, expectedRecords)) - assert.True(t, testutils.SameEndpoints(missingRecords, expectedMissingRecords)) } func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { @@ -981,86 +967,71 @@ func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + ForceUpdate: true, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: true, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, + ForceUpdate: false, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, + ForceUpdate: false, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: false, Labels: map[string]string{ // All the records of the zone are retrieved, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, + ForceUpdate: false, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - }, - } - - expectedMissingRecords := []*endpoint.Endpoint{ - { - DNSName: "txt.cname-oldformat.test-zone.example.org", - // owner is taken from the source record (A, CNAME, etc.) - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: endpoint.RecordTypeTXT, - Labels: endpoint.Labels{ - endpoint.OwnedRecordLabelKey: "oldformat.test-zone.example.org", - }, - }, - { - DNSName: "txt.a-oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: endpoint.RecordTypeTXT, - Labels: endpoint.Labels{ - endpoint.OwnedRecordLabelKey: "oldformat2.test-zone.example.org", - }, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + ForceUpdate: false, }, } r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{endpoint.RecordTypeCNAME, endpoint.RecordTypeA, endpoint.RecordTypeNS}, false, nil) records, _ := r.Records(ctx) - missingRecords := r.MissingRecords() assert.True(t, testutils.SameEndpoints(records, expectedRecords)) - assert.True(t, testutils.SameEndpoints(missingRecords, expectedMissingRecords)) } func TestCacheMethods(t *testing.T) { From ed49e67c00e113abfe024e14ad67a5ec34eb0b2b Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 25 May 2023 21:50:59 +0200 Subject: [PATCH 117/154] update planner tests to match forced update strategy Signed-off-by: Matias Charriere --- plan/plan_test.go | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/plan/plan_test.go b/plan/plan_test.go index 2b107d0e89..f02a72d151 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -51,9 +51,7 @@ type PlanTestSuite struct { domainFilterFiltered2 *endpoint.Endpoint domainFilterFiltered3 *endpoint.Endpoint domainFilterExcluded *endpoint.Endpoint - domainFilterFilteredTXT1 *endpoint.Endpoint - domainFilterFilteredTXT2 *endpoint.Endpoint - domainFilterExcludedTXT *endpoint.Endpoint + forceUpdate *endpoint.Endpoint } func (suite *PlanTestSuite) SetupTest() { @@ -233,20 +231,11 @@ func (suite *PlanTestSuite) SetupTest() { Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", } - suite.domainFilterFilteredTXT1 = &endpoint.Endpoint{ - DNSName: "a-foo.domain.tld", - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: "TXT", - } - suite.domainFilterFilteredTXT2 = &endpoint.Endpoint{ - DNSName: "cname-bar.domain.tld", - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: "TXT", - } - suite.domainFilterExcludedTXT = &endpoint.Endpoint{ - DNSName: "cname-bar.otherdomain.tld", - Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""}, - RecordType: "TXT", + suite.forceUpdate = &endpoint.Endpoint{ + DNSName: "foo.domain.tld", + Targets: endpoint.Targets{"1.2.3.5"}, + RecordType: "A", + ForceUpdate: true, } } @@ -661,19 +650,22 @@ func (suite *PlanTestSuite) TestDomainFiltersUpdate() { validateEntries(suite.T(), changes.Delete, expectedDelete) } -func (suite *PlanTestSuite) TestMissing() { - missing := []*endpoint.Endpoint{suite.domainFilterFilteredTXT1, suite.domainFilterFilteredTXT2, suite.domainFilterExcludedTXT} - expectedCreate := []*endpoint.Endpoint{suite.domainFilterFilteredTXT1, suite.domainFilterFilteredTXT2} +func (suite *PlanTestSuite) TestForceUpdate() { + current := []*endpoint.Endpoint{suite.forceUpdate} + desired := []*endpoint.Endpoint{suite.forceUpdate} + expectedUpdateOld := current + expectedUpdateNew := current p := &Plan{ Policies: []Policy{&SyncPolicy{}}, - Missing: missing, - DomainFilter: endpoint.NewDomainFilter([]string{"domain.tld"}), + Current: current, + Desired: desired, ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}, } changes := p.Calculate().Changes - validateEntries(suite.T(), changes.Create, expectedCreate) + validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew) + validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld) } func (suite *PlanTestSuite) TestAAAARecords() { From 44b5761330b7097e0bf31ad57eec9f57742a3d8c Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 15 Jun 2023 11:48:08 +0200 Subject: [PATCH 118/154] reimplement ForceUpdate using ProviderSpecific properties Signed-off-by: Matias Charriere --- registry/txt.go | 10 +++- registry/txt_test.go | 129 +++++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 62 deletions(-) diff --git a/registry/txt.go b/registry/txt.go index e00136cc9e..f7d79a6869 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -30,7 +30,10 @@ import ( "sigs.k8s.io/external-dns/provider" ) -const recordTemplate = "%{record_type}" +const ( + recordTemplate = "%{record_type}" + providerSpecificForceUpdate = "txt/force-update" +) // TXTRegistry implements registry interface with ownership implemented via associated TXT records type TXTRegistry struct { @@ -172,7 +175,7 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error desiredTXTs := im.generateTXTRecord(ep) for _, desiredTXT := range desiredTXTs { if _, exists := txtRecordsMap[desiredTXT.DNSName]; !exists { - ep.ForceUpdate = true + ep.WithProviderSpecific(providerSpecificForceUpdate, "true") } } } @@ -283,6 +286,9 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // PropertyValuesEqual compares two attribute values for equality func (im *TXTRegistry) PropertyValuesEqual(name string, previous string, current string) bool { + if name == "txt/force-update" { + return false + } return im.provider.PropertyValuesEqual(name, previous, current) } diff --git a/registry/txt_test.go b/registry/txt_test.go index 0e1fe3c83c..2493fbb117 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -868,71 +868,75 @@ func testTXTRegistryMissingRecordsNoPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: true, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, }, { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: true, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, - ForceUpdate: false, + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, // Only TXT records with the wrong heritage are returned by Records() { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, - ForceUpdate: false, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ // Records() retrieves all the records of the zone, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, }, { - DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "this-is-a-63-characters-long-label-that-we-do-expect-will-work.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, @@ -967,64 +971,69 @@ func testTXTRegistryMissingRecordsWithPrefix(t *testing.T) { }) expectedRecords := []*endpoint.Endpoint{ { - DNSName: "oldformat.test-zone.example.org", - Targets: endpoint.Targets{"foo.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: true, + DNSName: "oldformat.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, Labels: map[string]string{ // owner was added from the TXT record's target endpoint.OwnerLabelKey: "owner", }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, }, { - DNSName: "oldformat2.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: true, + DNSName: "oldformat2.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, + ProviderSpecific: []endpoint.ProviderSpecificProperty{ + { + Name: "txt/force-update", + Value: "true", + }, + }, }, { - DNSName: "newformat.test-zone.example.org", - Targets: endpoint.Targets{"foobar.nameserver.com"}, - RecordType: endpoint.RecordTypeNS, - ForceUpdate: false, + DNSName: "newformat.test-zone.example.org", + Targets: endpoint.Targets{"foobar.nameserver.com"}, + RecordType: endpoint.RecordTypeNS, Labels: map[string]string{ endpoint.OwnerLabelKey: "owner", }, }, { - DNSName: "noheritage.test-zone.example.org", - Targets: endpoint.Targets{"random"}, - RecordType: endpoint.RecordTypeTXT, - ForceUpdate: false, + DNSName: "noheritage.test-zone.example.org", + Targets: endpoint.Targets{"random"}, + RecordType: endpoint.RecordTypeTXT, Labels: map[string]string{ // No owner because it's not external-dns heritage endpoint.OwnerLabelKey: "", }, }, { - DNSName: "oldformat-otherowner.test-zone.example.org", - Targets: endpoint.Targets{"bar.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "oldformat-otherowner.test-zone.example.org", + Targets: endpoint.Targets{"bar.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, Labels: map[string]string{ // All the records of the zone are retrieved, no matter the owner endpoint.OwnerLabelKey: "otherowner", }, }, { - DNSName: "unmanaged1.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, - RecordType: endpoint.RecordTypeA, - ForceUpdate: false, + DNSName: "unmanaged1.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged1.loadbalancer.com"}, + RecordType: endpoint.RecordTypeA, }, { - DNSName: "unmanaged2.test-zone.example.org", - Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, - RecordType: endpoint.RecordTypeCNAME, - ForceUpdate: false, + DNSName: "unmanaged2.test-zone.example.org", + Targets: endpoint.Targets{"unmanaged2.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, }, } From df5e9aeacebe51dac7f71959fcf3bf0273fb19ef Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Thu, 15 Jun 2023 11:48:50 +0200 Subject: [PATCH 119/154] remove ForceUpdate property on endpoint after reimplementation Signed-off-by: Matias Charriere --- endpoint/endpoint.go | 13 +++++-------- internal/testutils/endpoint.go | 3 +-- plan/plan.go | 2 +- plan/plan_test.go | 25 ------------------------- 4 files changed, 7 insertions(+), 36 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 46370fe5e1..736f1e5740 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -170,8 +170,6 @@ type Endpoint struct { Targets Targets `json:"targets,omitempty"` // RecordType type of record, e.g. CNAME, A, AAAA, SRV, TXT etc RecordType string `json:"recordType,omitempty"` - // Force planner to update record - ForceUpdate bool `json:"forceUpdate,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 @@ -204,12 +202,11 @@ func NewEndpointWithTTL(dnsName, recordType string, ttl TTL, targets ...string) } return &Endpoint{ - DNSName: strings.TrimSuffix(dnsName, "."), - Targets: cleanTargets, - RecordType: recordType, - ForceUpdate: false, - Labels: NewLabels(), - RecordTTL: ttl, + DNSName: strings.TrimSuffix(dnsName, "."), + Targets: cleanTargets, + RecordType: recordType, + Labels: NewLabels(), + RecordTTL: ttl, } } diff --git a/internal/testutils/endpoint.go b/internal/testutils/endpoint.go index fe13fb9346..f8b4657958 100644 --- a/internal/testutils/endpoint.go +++ b/internal/testutils/endpoint.go @@ -63,8 +63,7 @@ func SameEndpoint(a, b *endpoint.Endpoint) bool { a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL && a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] && a.Labels[endpoint.OwnedRecordLabelKey] == b.Labels[endpoint.OwnedRecordLabelKey] && - SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific) && - a.ForceUpdate == b.ForceUpdate + SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific) } // SameEndpoints compares two slices of endpoints regardless of order diff --git a/plan/plan.go b/plan/plan.go index e9aab6fb71..312bb261b1 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -163,7 +163,7 @@ func (p *Plan) Calculate() *Plan { if row.current != nil && len(row.candidates) > 0 { // dns name is taken update := t.resolver.ResolveUpdate(row.current, row.candidates) // compare "update" to "current" to figure out if actual update is required - if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) || row.current.ForceUpdate { + if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) { inheritOwner(row.current, update) changes.UpdateNew = append(changes.UpdateNew, update) changes.UpdateOld = append(changes.UpdateOld, row.current) diff --git a/plan/plan_test.go b/plan/plan_test.go index f02a72d151..cc9e56bd5a 100644 --- a/plan/plan_test.go +++ b/plan/plan_test.go @@ -51,7 +51,6 @@ type PlanTestSuite struct { domainFilterFiltered2 *endpoint.Endpoint domainFilterFiltered3 *endpoint.Endpoint domainFilterExcluded *endpoint.Endpoint - forceUpdate *endpoint.Endpoint } func (suite *PlanTestSuite) SetupTest() { @@ -231,12 +230,6 @@ func (suite *PlanTestSuite) SetupTest() { Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", } - suite.forceUpdate = &endpoint.Endpoint{ - DNSName: "foo.domain.tld", - Targets: endpoint.Targets{"1.2.3.5"}, - RecordType: "A", - ForceUpdate: true, - } } func (suite *PlanTestSuite) TestSyncFirstRound() { @@ -650,24 +643,6 @@ func (suite *PlanTestSuite) TestDomainFiltersUpdate() { validateEntries(suite.T(), changes.Delete, expectedDelete) } -func (suite *PlanTestSuite) TestForceUpdate() { - current := []*endpoint.Endpoint{suite.forceUpdate} - desired := []*endpoint.Endpoint{suite.forceUpdate} - expectedUpdateOld := current - expectedUpdateNew := current - - p := &Plan{ - Policies: []Policy{&SyncPolicy{}}, - Current: current, - Desired: desired, - ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}, - } - - changes := p.Calculate().Changes - validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew) - validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld) -} - func (suite *PlanTestSuite) TestAAAARecords() { current := []*endpoint.Endpoint{} From bc893f1ad3cce256ab4128fa90a3d05b5c9deae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20J=2E=20Nu=C3=B1ez=20Madrazo?= Date: Thu, 15 Jun 2023 14:02:38 +0100 Subject: [PATCH 120/154] Rollback the go mod to the original version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro J. Nuñez Madrazo --- go.mod | 44 ++++++++++---------- go.sum | 124 +++++++++++++++++---------------------------------------- 2 files changed, 57 insertions(+), 111 deletions(-) diff --git a/go.mod b/go.mod index fb51f57184..4e25972893 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/ans-group/sdk-go v1.10.4 github.com/aws/aws-sdk-go v1.44.136 github.com/bodgit/tsig v1.2.2 - github.com/civo/civogo v0.3.37 + github.com/civo/civogo v0.3.33 github.com/cloudflare/cloudflare-go v0.58.1 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 github.com/datawire/ambassador v1.6.0 @@ -61,7 +61,7 @@ require ( go.etcd.io/etcd/api/v3 v3.5.8 go.etcd.io/etcd/client/v3 v3.5.8 go.uber.org/ratelimit v0.2.0 - golang.org/x/net v0.11.0 + golang.org/x/net v0.8.0 golang.org/x/oauth2 v0.5.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.110.0 @@ -69,8 +69,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 istio.io/api v0.0.0-20210128181506-0c4b8e54850f istio.io/client-go v0.0.0-20210128182905-ee2edd059e02 - k8s.io/api v0.27.1 - k8s.io/apimachinery v0.27.1 + k8s.io/api v0.26.0 + k8s.io/apimachinery v0.26.0 k8s.io/client-go v0.26.0 sigs.k8s.io/gateway-api v0.6.0 ) @@ -105,10 +105,10 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/strfmt v0.21.5 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/swag v0.19.14 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.13.0 // indirect @@ -118,7 +118,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -142,7 +142,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.3 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect @@ -176,13 +176,13 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.10.0 // indirect - golang.org/x/mod v0.9.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect google.golang.org/grpc v1.53.0 // indirect @@ -194,18 +194,14 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect - k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect - k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect moul.io/http2curl v1.0.0 // indirect sigs.k8s.io/controller-runtime v0.12.1 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) -replace ( - k8s.io/api => k8s.io/api v0.26.0 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.0 - k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a -) +replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a diff --git a/go.sum b/go.sum index 57cd6bfae3..12d013dced 100644 --- a/go.sum +++ b/go.sum @@ -161,7 +161,6 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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= @@ -209,8 +208,8 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/civo/civogo v0.3.37 h1:iNFsmv5PrfWy0J7JLw0sS0LhNaaR66m5aVRB3cvYSsA= -github.com/civo/civogo v0.3.37/go.mod h1:ovGwXtszFiTsVq1OgKG9CtE8q8TPm+4bwE13KuJBr9E= +github.com/civo/civogo v0.3.33 h1:asqRaD5Fp+JyPBXrsGqRbjTSTZ5zKeRhJrJfdV4bPTg= +github.com/civo/civogo v0.3.33/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak= 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/cloudflare/cloudflare-go v0.58.1 h1:+Tqt4N9nuNEMgSC3tCQOixyifU5jihaq+JfDQidTSgY= @@ -293,6 +292,7 @@ github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw 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= @@ -306,7 +306,6 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB 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.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= @@ -367,7 +366,6 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -390,16 +388,15 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds 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.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.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.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= 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= @@ -426,8 +423,8 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ 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 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 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= @@ -451,7 +448,6 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= @@ -543,9 +539,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/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/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= @@ -567,7 +562,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -586,7 +580,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= @@ -805,8 +798,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN 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/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -920,16 +913,7 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv 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.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= -github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= -github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= -github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= 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= @@ -941,16 +925,6 @@ github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4 github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= -github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= -github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= -github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= -github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= 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= @@ -1224,7 +1198,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/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.1/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= @@ -1308,9 +1281,8 @@ golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1344,13 +1316,10 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1404,23 +1373,15 @@ golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= 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= @@ -1523,13 +1484,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/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= @@ -1537,24 +1495,16 @@ golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1566,12 +1516,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.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= @@ -1651,14 +1597,10 @@ golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1763,7 +1705,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -1840,6 +1781,13 @@ istio.io/client-go v0.0.0-20210128182905-ee2edd059e02/go.mod h1:oXMjFUWhxlReUSbg istio.io/gogo-genproto v0.0.0-20190904133402-ee07f2785480/go.mod h1:uKtbae4K9k2rjjX4ToV0l6etglbc1i7gqQ94XdkshzY= istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE= istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs= +k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= +k8s.io/api v0.18.1/go.mod h1:3My4jorQWzSs5a+l7Ge6JBbIxChLnY8HnuT58ZWolss= +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.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= k8s.io/api v0.26.0 h1:IpPlZnxBpV1xl7TGk/X6lFtpgjgntCg8PJ+qrPHAC7I= k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo= @@ -1847,6 +1795,13 @@ k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJ k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= k8s.io/apiextensions-apiserver v0.20.4/go.mod h1:Hzebis/9c6Io5yzHp24Vg4XOkTp1ViMwKP/6gmpsfA4= k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= +k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apimachinery v0.18.1/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.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw= @@ -1881,7 +1836,6 @@ k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 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= @@ -1890,19 +1844,16 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= 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-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= -k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1918,9 +1869,8 @@ sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXe sigs.k8s.io/controller-tools v0.3.1-0.20200517180335-820a4a27ea84/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -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= From 531ca6624d70e38be87bc3e8d75bb340f6bd984a Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Thu, 15 Jun 2023 15:49:29 +0100 Subject: [PATCH 121/154] chore: Fixed gh workflow approve Signed-off-by: Steve Hipwell --- .github/workflows/gh-workflow-approve.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-workflow-approve.yaml b/.github/workflows/gh-workflow-approve.yaml index e3c13fdd98..71b51b0ae0 100644 --- a/.github/workflows/gh-workflow-approve.yaml +++ b/.github/workflows/gh-workflow-approve.yaml @@ -21,7 +21,7 @@ jobs: continue-on-error: true with: github-token: ${{ secrets.GITHUB_TOKEN }} - debug: ${{ secrets.ACTIONS_RUNNER_DEBUG }} + debug: ${{ secrets.ACTIONS_RUNNER_DEBUG == 'true' }} script: | const result = await github.rest.actions.listWorkflowRunsForRepo({ owner: context.repo.owner, From a3bc44fc943f9406b1c3afeb15b17398c9b6ffb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Fri, 16 Jun 2023 10:59:03 +0200 Subject: [PATCH 122/154] update github.com/golang-jwt/jwt/v4 and github.com/emicklei/go-restful/v3 to fix vulnerabilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- go.mod | 4 ++-- go.sum | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 227ccc6081..0d8aa35267 100644 --- a/go.mod +++ b/go.mod @@ -99,7 +99,7 @@ require ( github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/structs v1.1.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -117,7 +117,7 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.4.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect diff --git a/go.sum b/go.sum index ae19339555..ca6c39a458 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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= @@ -312,6 +313,8 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= 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= @@ -509,11 +512,14 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 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= @@ -558,6 +564,7 @@ github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkY 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/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -638,6 +645,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de 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/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -1637,6 +1645,7 @@ 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= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= 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= From 109101147881cc622cd5f3eda6f7bd5b66c438fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Fri, 16 Jun 2023 11:00:04 +0200 Subject: [PATCH 123/154] go mod tidy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandor Szücs --- go.mod | 3 +-- go.sum | 45 ++------------------------------------------- 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index 0d8aa35267..2378cf55f1 100644 --- a/go.mod +++ b/go.mod @@ -64,6 +64,7 @@ require ( golang.org/x/net v0.8.0 golang.org/x/oauth2 v0.5.0 golang.org/x/sync v0.1.0 + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af google.golang.org/api v0.110.0 gopkg.in/ns1/ns1-go.v2 v2.7.4 gopkg.in/yaml.v2 v2.4.0 @@ -113,7 +114,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.13.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect - github.com/go-stack/stack v1.8.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -182,7 +182,6 @@ require ( golang.org/x/sys v0.6.0 // indirect golang.org/x/term v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect - golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect golang.org/x/tools v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect diff --git a/go.sum b/go.sum index ca6c39a458..6b20838e8d 100644 --- a/go.sum +++ b/go.sum @@ -86,7 +86,6 @@ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 h1:/ZCtF9JC9VyTN2bdwtHnlpCoJOWxZ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1/go.mod h1:vdlVHq8oUD8W8yUr53RSZ9hKkOcboFcgvhS6nMKH+qc= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= -github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= @@ -162,13 +161,11 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -193,8 +190,6 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+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/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= -github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= github.com/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -311,8 +306,6 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB 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.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= @@ -373,7 +366,6 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -387,7 +379,6 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 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/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= @@ -424,7 +415,6 @@ github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pL 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/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlONADE= github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= @@ -439,13 +429,12 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ 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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= @@ -458,7 +447,6 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr 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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= @@ -512,12 +500,9 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -564,7 +549,6 @@ github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkY 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/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -616,8 +600,6 @@ github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1a github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 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/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= -github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= github.com/gophercloud/gophercloud v1.4.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -645,7 +627,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de 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/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -675,7 +656,6 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX 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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -712,19 +692,14 @@ github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFK github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE/Tq8= github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -790,7 +765,6 @@ github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= @@ -861,7 +835,6 @@ github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08 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/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c= @@ -952,7 +925,7 @@ github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4 github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= 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= @@ -1244,7 +1217,6 @@ go.etcd.io/etcd/client/v3 v3.5.8/go.mod h1:idZYIPVkttBJBiRigkB5EM0MmEyx8jcl18zCV 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.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= @@ -1299,20 +1271,16 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh 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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1349,7 +1317,6 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1413,8 +1380,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1538,8 +1503,6 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1553,8 +1516,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1637,7 +1598,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1645,7 +1605,6 @@ 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= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= 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= From 922e0eb31acda5a7e6d2fc7dd609ad63378eb694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Jun 2023 11:35:43 +0000 Subject: [PATCH 124/154] build(deps): bump the dev-dependencies group with 40 updates Bumps the dev-dependencies group with 40 updates: [github.com/Azure/azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go), [github.com/Azure/go-autorest/autorest](https://github.com/Azure/go-autorest), [github.com/Azure/go-autorest/autorest/adal](https://github.com/Azure/go-autorest), [github.com/F5Networks/k8s-bigip-ctlr/v2](https://github.com/F5Networks/k8s-bigip-ctlr), [github.com/IBM/networking-go-sdk](https://github.com/IBM/networking-go-sdk), [github.com/StackExchange/dnscontrol/v3](https://github.com/StackExchange/dnscontrol), [github.com/alecthomas/kingpin](https://github.com/alecthomas/kingpin), [github.com/aliyun/alibaba-cloud-sdk-go](https://github.com/aliyun/alibaba-cloud-sdk-go), [github.com/ans-group/sdk-go](https://github.com/ans-group/sdk-go), [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go), [github.com/cloudflare/cloudflare-go](https://github.com/cloudflare/cloudflare-go), [github.com/exoscale/egoscale](https://github.com/exoscale/egoscale), [github.com/infobloxopen/infoblox-go-client/v2](https://github.com/infobloxopen/infoblox-go-client), [github.com/linode/linodego](https://github.com/linode/linodego), [github.com/maxatome/go-testdeep](https://github.com/maxatome/go-testdeep), [github.com/openshift/api](https://github.com/openshift/api), [github.com/openshift/client-go](https://github.com/openshift/client-go), [github.com/oracle/oci-go-sdk/v65](https://github.com/oracle/oci-go-sdk), [github.com/ovh/go-ovh](https://github.com/ovh/go-ovh), [github.com/pluralsh/gqlclient](https://github.com/pluralsh/gqlclient), [github.com/projectcontour/contour](https://github.com/projectcontour/contour), [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang), [github.com/scaleway/scaleway-sdk-go](https://github.com/scaleway/scaleway-sdk-go), [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/ultradns/ultradns-sdk-go](https://github.com/ultradns/ultradns-sdk-go), [github.com/vinyldns/go-vinyldns](https://github.com/vinyldns/go-vinyldns), [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd), [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd), [golang.org/x/net](https://github.com/golang/net), [golang.org/x/oauth2](https://github.com/golang/oauth2), [golang.org/x/sync](https://github.com/golang/sync), [google.golang.org/api](https://github.com/googleapis/google-api-go-client), gopkg.in/ns1/ns1-go.v2, [istio.io/client-go](https://github.com/istio/client-go), [k8s.io/api](https://github.com/kubernetes/api), [k8s.io/client-go](https://github.com/kubernetes/client-go) and [sigs.k8s.io/gateway-api](https://github.com/kubernetes-sigs/gateway-api). Updates `github.com/Azure/azure-sdk-for-go` from 66.0.0+incompatible to 68.0.0+incompatible - [Release notes](https://github.com/Azure/azure-sdk-for-go/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/release.md) - [Commits](https://github.com/Azure/azure-sdk-for-go/compare/v66.0.0...v68.0.0) Updates `github.com/Azure/go-autorest/autorest` from 0.11.28 to 0.11.29 - [Release notes](https://github.com/Azure/go-autorest/releases) - [Changelog](https://github.com/Azure/go-autorest/blob/main/CHANGELOG.md) - [Commits](https://github.com/Azure/go-autorest/compare/autorest/v0.11.28...autorest/v0.11.29) Updates `github.com/Azure/go-autorest/autorest/adal` from 0.9.22 to 0.9.23 - [Release notes](https://github.com/Azure/go-autorest/releases) - [Changelog](https://github.com/Azure/go-autorest/blob/main/CHANGELOG.md) - [Commits](https://github.com/Azure/go-autorest/compare/autorest/adal/v0.9.22...autorest/adal/v0.9.23) Updates `github.com/F5Networks/k8s-bigip-ctlr/v2` from 2.11.1 to 2.13.0 - [Release notes](https://github.com/F5Networks/k8s-bigip-ctlr/releases) - [Changelog](https://github.com/F5Networks/k8s-bigip-ctlr/blob/master/docs/RELEASE-NOTES.rst) - [Commits](https://github.com/F5Networks/k8s-bigip-ctlr/compare/v2.11.1...v2.13.0) Updates `github.com/IBM/networking-go-sdk` from 0.36.0 to 0.42.0 - [Release notes](https://github.com/IBM/networking-go-sdk/releases) - [Changelog](https://github.com/IBM/networking-go-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/IBM/networking-go-sdk/compare/v0.36.0...v0.42.0) Updates `github.com/StackExchange/dnscontrol/v3` from 3.27.1 to 3.31.6 - [Release notes](https://github.com/StackExchange/dnscontrol/releases) - [Changelog](https://github.com/StackExchange/dnscontrol/blob/master/documentation/release-engineering.md) - [Commits](https://github.com/StackExchange/dnscontrol/commits) Updates `github.com/alecthomas/kingpin` from 2.2.5+incompatible to 2.2.6+incompatible - [Release notes](https://github.com/alecthomas/kingpin/releases) - [Commits](https://github.com/alecthomas/kingpin/compare/v2.2.5...v2.2.6) Updates `github.com/aliyun/alibaba-cloud-sdk-go` from 1.62.4 to 1.62.377 - [Release notes](https://github.com/aliyun/alibaba-cloud-sdk-go/releases) - [Changelog](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/ChangeLog.txt) - [Commits](https://github.com/aliyun/alibaba-cloud-sdk-go/compare/v1.62.4...v1.62.377) Updates `github.com/ans-group/sdk-go` from 1.10.4 to 1.16.5 - [Release notes](https://github.com/ans-group/sdk-go/releases) - [Commits](https://github.com/ans-group/sdk-go/compare/v1.10.4...v1.16.5) Updates `github.com/aws/aws-sdk-go` from 1.44.136 to 1.44.283 - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.136...v1.44.283) Updates `github.com/cloudflare/cloudflare-go` from 0.58.1 to 0.69.0 - [Release notes](https://github.com/cloudflare/cloudflare-go/releases) - [Changelog](https://github.com/cloudflare/cloudflare-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/cloudflare/cloudflare-go/compare/v0.58.1...v0.69.0) Updates `github.com/exoscale/egoscale` from 0.97.0 to 1.19.0 - [Release notes](https://github.com/exoscale/egoscale/releases) - [Changelog](https://github.com/exoscale/egoscale/blob/master/CHANGELOG.md) - [Commits](https://github.com/exoscale/egoscale/commits) Updates `github.com/infobloxopen/infoblox-go-client/v2` from 2.1.2-0.20220407114022-6f4c71443168 to 2.3.0 - [Release notes](https://github.com/infobloxopen/infoblox-go-client/releases) - [Changelog](https://github.com/infobloxopen/infoblox-go-client/blob/master/CHANGELOG.rst) - [Commits](https://github.com/infobloxopen/infoblox-go-client/commits/v2.3.0) Updates `github.com/linode/linodego` from 1.9.1 to 1.17.0 - [Release notes](https://github.com/linode/linodego/releases) - [Commits](https://github.com/linode/linodego/compare/v1.9.1...v1.17.0) Updates `github.com/maxatome/go-testdeep` from 1.12.0 to 1.13.0 - [Release notes](https://github.com/maxatome/go-testdeep/releases) - [Commits](https://github.com/maxatome/go-testdeep/compare/v1.12.0...v1.13.0) Updates `github.com/openshift/api` from 0.0.0-20210315202829-4b79815405ec to 3.9.0+incompatible - [Commits](https://github.com/openshift/api/commits) Updates `github.com/openshift/client-go` from 0.0.0-20210112165513-ebc401615f47 to 3.9.0+incompatible - [Commits](https://github.com/openshift/client-go/commits/v3.9.0) Updates `github.com/oracle/oci-go-sdk/v65` from 65.35.0 to 65.41.0 - [Release notes](https://github.com/oracle/oci-go-sdk/releases) - [Changelog](https://github.com/oracle/oci-go-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/oracle/oci-go-sdk/compare/v65.35.0...v65.41.0) Updates `github.com/ovh/go-ovh` from 1.1.0 to 1.4.1 - [Release notes](https://github.com/ovh/go-ovh/releases) - [Commits](https://github.com/ovh/go-ovh/compare/v1.1.0...v1.4.1) Updates `github.com/pluralsh/gqlclient` from 1.1.6 to 1.3.17 - [Release notes](https://github.com/pluralsh/gqlclient/releases) - [Changelog](https://github.com/pluralsh/gqlclient/blob/main/.releaserc) - [Commits](https://github.com/pluralsh/gqlclient/compare/v1.1.6...v1.3.17) Updates `github.com/projectcontour/contour` from 1.23.2 to 1.25.0 - [Release notes](https://github.com/projectcontour/contour/releases) - [Changelog](https://github.com/projectcontour/contour/blob/main/RELEASES.md) - [Commits](https://github.com/projectcontour/contour/compare/v1.23.2...v1.25.0) Updates `github.com/prometheus/client_golang` from 1.15.1 to 1.16.0 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0) Updates `github.com/scaleway/scaleway-sdk-go` from 1.0.0-beta.7.0.20210127161313-bd30bebeac4f to 1.0.0-beta.17 - [Release notes](https://github.com/scaleway/scaleway-sdk-go/releases) - [Changelog](https://github.com/scaleway/scaleway-sdk-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/scaleway/scaleway-sdk-go/commits/v1.0.0-beta.17) Updates `github.com/sirupsen/logrus` from 1.9.0 to 1.9.3 - [Release notes](https://github.com/sirupsen/logrus/releases) - [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md) - [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common` from 1.0.599 to 1.0.682 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.599...v1.0.682) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod` from 1.0.344 to 1.0.682 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.344...v1.0.682) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns` from 1.0.599 to 1.0.682 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.599...v1.0.682) Updates `github.com/ultradns/ultradns-sdk-go` from 0.0.0-20200616202852-e62052662f60 to 1.3.7 - [Release notes](https://github.com/ultradns/ultradns-sdk-go/releases) - [Changelog](https://github.com/ultradns/ultradns-sdk-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/ultradns/ultradns-sdk-go/commits/v1.3.7) Updates `github.com/vinyldns/go-vinyldns` from 0.0.0-20200211145900-fe8a3d82e556 to 0.9.16 - [Release notes](https://github.com/vinyldns/go-vinyldns/releases) - [Commits](https://github.com/vinyldns/go-vinyldns/commits/v0.9.16) Updates `go.etcd.io/etcd/api/v3` from 3.5.8 to 3.5.9 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.8...v3.5.9) Updates `go.etcd.io/etcd/client/v3` from 3.5.8 to 3.5.9 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.8...v3.5.9) Updates `golang.org/x/net` from 0.10.0 to 0.11.0 - [Commits](https://github.com/golang/net/compare/v0.10.0...v0.11.0) Updates `golang.org/x/oauth2` from 0.7.0 to 0.9.0 - [Commits](https://github.com/golang/oauth2/compare/v0.7.0...v0.9.0) Updates `golang.org/x/sync` from 0.2.0 to 0.3.0 - [Commits](https://github.com/golang/sync/compare/v0.2.0...v0.3.0) Updates `google.golang.org/api` from 0.120.0 to 0.128.0 - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.120.0...v0.128.0) Updates `gopkg.in/ns1/ns1-go.v2` from 2.7.4 to 2.7.6 Updates `istio.io/client-go` from 0.0.0-20210128182905-ee2edd059e02 to 1.18.0 - [Commits](https://github.com/istio/client-go/commits/v1.18.0) Updates `k8s.io/api` from 0.27.0 to 0.27.3 - [Commits](https://github.com/kubernetes/api/compare/v0.27.0...v0.27.3) Updates `k8s.io/client-go` from 0.27.0 to 0.27.3 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.27.0...v0.27.3) Updates `sigs.k8s.io/gateway-api` from 0.6.2 to 0.7.1 - [Release notes](https://github.com/kubernetes-sigs/gateway-api/releases) - [Changelog](https://github.com/kubernetes-sigs/gateway-api/blob/main/CHANGELOG.md) - [Commits](https://github.com/kubernetes-sigs/gateway-api/compare/v0.6.2...v0.7.1) --- updated-dependencies: - dependency-name: github.com/Azure/azure-sdk-for-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/Azure/go-autorest/autorest dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/Azure/go-autorest/autorest/adal dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/F5Networks/k8s-bigip-ctlr/v2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/IBM/networking-go-sdk dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/StackExchange/dnscontrol/v3 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/alecthomas/kingpin dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/aliyun/alibaba-cloud-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/ans-group/sdk-go dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/cloudflare/cloudflare-go dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/exoscale/egoscale dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/infobloxopen/infoblox-go-client/v2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/linode/linodego dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/maxatome/go-testdeep dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/openshift/api dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/openshift/client-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/oracle/oci-go-sdk/v65 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/ovh/go-ovh dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/pluralsh/gqlclient dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/projectcontour/contour dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/scaleway/scaleway-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/sirupsen/logrus dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/ultradns/ultradns-sdk-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/vinyldns/go-vinyldns dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: go.etcd.io/etcd/api/v3 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: go.etcd.io/etcd/client/v3 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: golang.org/x/sync dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: gopkg.in/ns1/ns1-go.v2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: istio.io/client-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: sigs.k8s.io/gateway-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 193 +++++++-------- go.sum | 736 +++++++++++++++++++++++---------------------------------- 2 files changed, 394 insertions(+), 535 deletions(-) diff --git a/go.mod b/go.mod index 2378cf55f1..7d5b70a146 100644 --- a/go.mod +++ b/go.mod @@ -4,80 +4,80 @@ go 1.20 require ( cloud.google.com/go/compute/metadata v0.2.3 - github.com/Azure/azure-sdk-for-go v66.0.0+incompatible - github.com/Azure/go-autorest/autorest v0.11.28 - github.com/Azure/go-autorest/autorest/adal v0.9.21 + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible + github.com/Azure/go-autorest/autorest v0.11.29 + github.com/Azure/go-autorest/autorest/adal v0.9.23 github.com/Azure/go-autorest/autorest/to v0.4.0 - github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 + github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.0 github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 github.com/IBM/go-sdk-core/v5 v5.13.4 - github.com/IBM/networking-go-sdk v0.36.0 - github.com/StackExchange/dnscontrol/v3 v3.27.1 + github.com/IBM/networking-go-sdk v0.42.0 + github.com/StackExchange/dnscontrol/v3 v3.31.6 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 - github.com/alecthomas/kingpin v2.2.5+incompatible - github.com/aliyun/alibaba-cloud-sdk-go v1.62.4 - github.com/ans-group/sdk-go v1.10.4 - github.com/aws/aws-sdk-go v1.44.136 + github.com/alecthomas/kingpin v2.2.6+incompatible + github.com/aliyun/alibaba-cloud-sdk-go v1.62.377 + github.com/ans-group/sdk-go v1.16.5 + github.com/aws/aws-sdk-go v1.44.283 github.com/bodgit/tsig v1.2.2 github.com/civo/civogo v0.3.14 - github.com/cloudflare/cloudflare-go v0.58.1 + github.com/cloudflare/cloudflare-go v0.69.0 github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 github.com/datawire/ambassador v1.6.0 github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba - github.com/digitalocean/godo v1.97.0 - github.com/dnsimple/dnsimple-go v1.0.1 - github.com/exoscale/egoscale v0.97.0 + github.com/digitalocean/godo v1.99.0 + github.com/dnsimple/dnsimple-go v1.2.0 + github.com/exoscale/egoscale v1.19.0 github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 github.com/go-gandi/go-gandi v0.6.0 github.com/google/go-cmp v0.5.9 github.com/gophercloud/gophercloud v1.4.0 github.com/hooklift/gowsdl v0.5.0 - github.com/infobloxopen/infoblox-go-client/v2 v2.1.2-0.20220407114022-6f4c71443168 + github.com/infobloxopen/infoblox-go-client/v2 v2.3.0 github.com/linki/instrumented_http v0.3.0 - github.com/linode/linodego v1.9.1 - github.com/maxatome/go-testdeep v1.12.0 - github.com/miekg/dns v1.1.51 + github.com/linode/linodego v1.17.0 + github.com/maxatome/go-testdeep v1.13.0 + github.com/miekg/dns v1.1.54 github.com/nesv/go-dynect v0.6.0 github.com/nic-at/rc0go v1.1.1 github.com/onsi/ginkgo v1.16.5 - github.com/openshift/api v0.0.0-20210315202829-4b79815405ec - github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47 - github.com/oracle/oci-go-sdk/v65 v65.35.0 - github.com/ovh/go-ovh v1.1.0 + github.com/openshift/api v3.9.0+incompatible + github.com/openshift/client-go v3.9.0+incompatible + github.com/oracle/oci-go-sdk/v65 v65.41.0 + github.com/ovh/go-ovh v1.4.1 github.com/pkg/errors v0.9.1 - github.com/pluralsh/gqlclient v1.1.6 - github.com/projectcontour/contour v1.23.2 - github.com/prometheus/client_golang v1.14.0 - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f - github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.2 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.599 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.344 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.599 - github.com/transip/gotransip/v6 v6.19.0 - github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60 - github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 + github.com/pluralsh/gqlclient v1.3.17 + github.com/projectcontour/contour v1.25.0 + github.com/prometheus/client_golang v1.16.0 + github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682 + github.com/transip/gotransip/v6 v6.20.0 + github.com/ultradns/ultradns-sdk-go v1.3.7 + github.com/vinyldns/go-vinyldns v0.9.16 github.com/vultr/govultr/v2 v2.17.2 - go.etcd.io/etcd/api/v3 v3.5.8 - go.etcd.io/etcd/client/v3 v3.5.8 + go.etcd.io/etcd/api/v3 v3.5.9 + go.etcd.io/etcd/client/v3 v3.5.9 go.uber.org/ratelimit v0.2.0 - golang.org/x/net v0.8.0 - golang.org/x/oauth2 v0.5.0 - golang.org/x/sync v0.1.0 - golang.org/x/time v0.0.0-20220922220347-f3bd1da661af - google.golang.org/api v0.110.0 - gopkg.in/ns1/ns1-go.v2 v2.7.4 + golang.org/x/net v0.11.0 + golang.org/x/oauth2 v0.9.0 + golang.org/x/sync v0.3.0 + golang.org/x/time v0.3.0 + google.golang.org/api v0.128.0 + gopkg.in/ns1/ns1-go.v2 v2.7.6 gopkg.in/yaml.v2 v2.4.0 - istio.io/api v0.0.0-20210128181506-0c4b8e54850f - istio.io/client-go v0.0.0-20210128182905-ee2edd059e02 - k8s.io/api v0.26.0 - k8s.io/apimachinery v0.26.0 - k8s.io/client-go v0.26.0 - sigs.k8s.io/gateway-api v0.6.0 + istio.io/api v0.0.0-20230524015941-fa6c5f7916bf + istio.io/client-go v1.18.0 + k8s.io/api v0.27.3 + k8s.io/apimachinery v0.27.3 + k8s.io/client-go v0.27.3 + sigs.k8s.io/gateway-api v0.7.1 ) require ( - cloud.google.com/go/compute v1.18.0 // indirect + cloud.google.com/go/compute v1.19.3 // indirect code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect @@ -85,11 +85,8 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Masterminds/semver v1.4.2 // indirect github.com/Yamashou/gqlgenc v0.11.0 // indirect - github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 // indirect - github.com/alecthomas/colour v0.1.0 // indirect - github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/ans-group/go-durationstring v1.2.0 // indirect @@ -97,41 +94,45 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deepmap/oapi-codegen v1.9.1 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fatih/structs v1.1.0 // indirect + github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/strfmt v0.21.5 // indirect - github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.13.0 // indirect - github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect + github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic v0.6.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/s2a-go v0.1.4 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect + github.com/googleapis/gax-go/v2 v2.10.0 // indirect + github.com/gorilla/mux v1.8.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect @@ -143,9 +144,10 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.3 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -157,49 +159,56 @@ require ( github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/peterhellberg/link v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.43.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/schollz/progressbar/v3 v3.8.6 // indirect github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect github.com/smartystreets/gunit v1.3.4 // indirect github.com/sony/gobreaker v0.5.0 // indirect + github.com/spf13/afero v1.9.3 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.15.0 // indirect github.com/stretchr/objx v0.5.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect github.com/terra-farm/udnssdk v1.3.5 // indirect - github.com/vektah/gqlparser/v2 v2.5.0 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.8 // indirect + github.com/vektah/gqlparser/v2 v2.5.1 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.6.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/tools v0.8.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/go-playground/validator.v9 v9.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/resty.v1 v1.12.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect moul.io/http2curl v1.0.0 // indirect - sigs.k8s.io/controller-runtime v0.12.1 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/controller-runtime v0.14.6 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 6b20838e8d..72077643c7 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -14,21 +15,21 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -38,41 +39,36 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= 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= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 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/azure-sdk-for-go v66.0.0+incompatible h1:bmmC38SlE8/E81nNADlgmVGurPWMHDX2YNXVQMrBpEE= -github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= +github.com/Azure/azure-sdk-for-go v68.0.0+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 v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+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 v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= -github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= +github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= +github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk= -github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= 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/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= @@ -81,16 +77,14 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/F5Networks/f5-ipam-controller v0.1.6-0.20211217134627-c2be8b459270/go.mod h1:XBOjYUVRKG8q8atIpNmil/XF6RAGVekqfbeNQludcV4= -github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 h1:/ZCtF9JC9VyTN2bdwtHnlpCoJOWxZON5Sh7QDtFlB1E= -github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1/go.mod h1:vdlVHq8oUD8W8yUr53RSZ9hKkOcboFcgvhS6nMKH+qc= +github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.0 h1:oHBU4lCjA3SeuF7Q2uZ/YH169N3f+M7fgg2lJ88R6dk= +github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.0/go.mod h1:GJ5fTJ9GuGe2CzEYd8hk/KinNXDNJ0QYqWluiPdLn/s= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= -github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= -github.com/IBM/networking-go-sdk v0.36.0 h1:ADntTsRM8DMZOxS9TYGTAL6i0zw9V2L7OeLFd9Czntk= -github.com/IBM/networking-go-sdk v0.36.0/go.mod h1:tDJtlySQC/txyejU9KeQ27Amc6xKH0MwHFE/B2+Sn5w= +github.com/IBM/networking-go-sdk v0.42.0 h1:tgUwkAdKRnbnovAUxRkHHFajnnjVrhbTXv5YLjRHXAo= +github.com/IBM/networking-go-sdk v0.42.0/go.mod h1:lTUZwtUkMANMnrLHFIgRhHrkBfwASY/Iho1fabaPHxo= 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= @@ -105,7 +99,6 @@ github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHS 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/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= 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= @@ -117,8 +110,8 @@ github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a/go.mod h1:AsBYmtPY5rg 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/StackExchange/dnscontrol/v3 v3.27.1 h1:7kU3X/prVVnMA7e7AOu7dpwo70WnNA3mJ5FdPoZTz8A= -github.com/StackExchange/dnscontrol/v3 v3.27.1/go.mod h1:ZpOpcdK5F2vLFL+SbbDXXksewqlB/WIsSfytOCUD64U= +github.com/StackExchange/dnscontrol/v3 v3.31.6 h1:QIfe5mN+PveeW0DeE+M7wvWkYpeTtT3IKJdnUb94qps= +github.com/StackExchange/dnscontrol/v3 v3.31.6/go.mod h1:ySJb55bSINayq5h9sK/BePPp52yLAXXCisd0DTs9Ies= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Yamashou/gqlgenc v0.11.0 h1:y6I7CDrUdY4JBxfwss9168HTP5k/CdExLV5+YPG/3nY= github.com/Yamashou/gqlgenc v0.11.0/go.mod h1:OeQhghEgvGWvRwzx9XjMeg3FUQOHnTo5/12iuJSJxLg= @@ -126,25 +119,19 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 h1:F1j7z+/DKEsYqZNoxC6wvfmaiDneLsQOFQmuq9NADSY= github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2/go.mod h1:QlXr/TrICfQ/ANa76sLeQyhAJyNR9sEcfNuZBkY9jgY= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= -github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= -github.com/alecthomas/colour v0.1.0 h1:nOE9rJm6dsZ66RGWYSFrXw461ZIt9A6+nHgL7FRrDUk= -github.com/alecthomas/colour v0.1.0/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= -github.com/alecthomas/kingpin v2.2.5+incompatible h1:umWl1NNd72+ZvRti3T9C0SYean2hPZ7ZhxU8bsgc9BQ= -github.com/alecthomas/kingpin v2.2.5+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= -github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c h1:MVVbswUlqicyj8P/JljoocA7AyCo62gzD0O7jfvrhtE= -github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +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-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +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/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4= github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.4 h1:PvdgtaX+aDehbXZvxgQDRRCPGsPnC1LNAXi84Iusykc= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.4/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.377 h1:6czd9jysvWELv3Yiip7dZJhBVKojt+GdWIrddzokEgY= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.377/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -152,8 +139,9 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U= github.com/ans-group/go-durationstring v1.2.0 h1:UJIuQATkp0t1rBvZsHRwki33YHV9E+Ulro+3NbMB7MM= github.com/ans-group/go-durationstring v1.2.0/go.mod h1:QGF9Mdpq9058QXaut8r55QWu6lcHX6i/GvF1PZVkV6o= -github.com/ans-group/sdk-go v1.10.4 h1:wZzojt99wtVIEHs8zNQzp1Xhqme5tD5NqMM1VLmG6xQ= -github.com/ans-group/sdk-go v1.10.4/go.mod h1:XSKXEDfKobnDtZoyia5DhJxxaDMcCjr76e1KJ9dU/xc= +github.com/ans-group/sdk-go v1.16.5 h1:FoBcdhM209iS2EfjVfq98GrDJNlJRu2mygZ0Xi8Mb3Q= +github.com/ans-group/sdk-go v1.16.5/go.mod h1:p1vrXBxHPvMOGlS4sFUSgeLeKAl9vIe/lJ6UaExe49A= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 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= @@ -172,12 +160,10 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W 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.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= -github.com/aws/aws-sdk-go v1.44.136 h1:J1KJJssa8pjU8jETYUxwRS37KTcxjACfKd9GK8t+5ZU= -github.com/aws/aws-sdk-go v1.44.136/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.283 h1:ObMaIvdhHJM2sIrbcljd7muHBaFb+Kp/QsX6iflGDg4= +github.com/aws/aws-sdk-go v1.44.283/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 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -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= @@ -185,14 +171,13 @@ 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/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 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/blang/semver v3.5.1+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/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= 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= @@ -201,7 +186,6 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH 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.1.2/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= @@ -212,13 +196,20 @@ github.com/civo/civogo v0.3.14 h1:W+o+hFXtEhWyJOmZOm2C5s8OEorSXGP6eyPYOa69NA8= github.com/civo/civogo v0.3.14/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak= 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/cloudflare/cloudflare-go v0.58.1 h1:+Tqt4N9nuNEMgSC3tCQOixyifU5jihaq+JfDQidTSgY= -github.com/cloudflare/cloudflare-go v0.58.1/go.mod h1:QaA8x4JI0/gA/tni1nTdyimFuyEGJi8cB7YSGoFhXFo= +github.com/cloudflare/cloudflare-go v0.69.0 h1:DHRjCQyM0p4qd3e0t3wnUNtRso1BQPUe4BtMAxZjKqY= +github.com/cloudflare/cloudflare-go v0.69.0/go.mod h1:A6gZktcMokwEgzoAP4BbVDoUU7VorNFAU7FzfIejVF8= 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 v0.0.0-20200324003616-bae28a880fdb/go.mod h1:HNVadOiXCy7Jk3R2knJ+qm++zkncJxxBMpjdGgJ+UJc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200324003616-bae28a880fdb/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +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-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +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= @@ -236,7 +227,6 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG 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/etcd v3.3.13+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= @@ -244,8 +234,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf 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/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27wIbmOGUs7RIbVgPEjb31ehTVniDwPGXyMxm5U= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -254,8 +244,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma 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/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/datawire/ambassador v1.6.0 h1:4KduhY/wqtv0jK8sMVQNtENHy9fmoXugsuFp/UrM0Ts= github.com/datawire/ambassador v1.6.0/go.mod h1:mV5EhoG/NnHBsffmLnjrq+x4ZNkYDWFZXW9R+AueUiE= @@ -264,10 +252,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= -github.com/deepmap/oapi-codegen v1.9.1 h1:yHmEnA7jSTUMQgV+uN02WpZtwHnz2CBW3mZRIxr1vtI= -github.com/deepmap/oapi-codegen v1.9.1/go.mod h1:PLqNAhdedP8ttRpBBkzLKU3bp+Fpy+tTgeAMlztR2cw= 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 h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4= @@ -275,12 +259,12 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l 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/digitalocean/godo v1.97.0 h1:p9w1yCcWMZcxFSLPToNGXA96WfUVLXqoHti6GzVomL4= -github.com/digitalocean/godo v1.97.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA= -github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= +github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= +github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnsimple/dnsimple-go v1.0.1 h1:ueDji5xvz6+hLA4JPNvOXGYGHelex0TT7uXdN5ZEWnQ= -github.com/dnsimple/dnsimple-go v1.0.1/go.mod h1:iw/53UDs5RV4ptHVyNrBBr7GHKnndETsP0J/n/JVnA4= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnsimple/dnsimple-go v1.2.0 h1:ddTGyLVKly5HKb5L65AkLqFqwZlWo3WnR0BlFZlIddM= +github.com/dnsimple/dnsimple-go v1.2.0/go.mod h1:z/cs26v/eiRvUyXsHQBLd8lWF8+cD6GbmkPH84plM4U= 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= @@ -313,41 +297,40 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s 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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/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/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 v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/exoscale/egoscale v0.97.0 h1:9DRSdFxepQrm/BOX/tvMXmfeN7d1row9N/+D9wrFp8E= -github.com/exoscale/egoscale v0.97.0/go.mod h1:BAb9p4rmyU+Wl400CJZO5270H2sXtdsZjLcm5xMKkz4= +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/exoscale/egoscale v1.19.0 h1:DbSyyzaPyxDBgGOuduCU26rQ4PJb/GP+8srXRabRf5U= +github.com/exoscale/egoscale v1.19.0/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/f5devcentral/go-bigip/f5teem v0.0.0-20210918163638-28fdd0579913/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= -github.com/f5devcentral/mockhttpclient v0.0.0-20210630101009-cc12e8b81051/go.mod h1:g2/ykgb7Fzf6ag/pYv0LfcwSH8z46TnjFOF3rWyh01I= 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/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= 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/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getkin/kin-openapi v0.87.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= 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/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= 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-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gandi/go-gandi v0.6.0 h1:RgFoevggRRp7hF9XsOmWmtwbUg2axhe2ygEdd6Mtstc= github.com/go-gandi/go-gandi v0.6.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -357,17 +340,13 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 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-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/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-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= @@ -379,7 +358,6 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 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/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= @@ -388,15 +366,15 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds 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.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.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.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/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= @@ -410,12 +388,10 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd 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/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= 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/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= @@ -423,71 +399,40 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ 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.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ= github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4= -github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY= -github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= -github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= 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.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.7.8/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -495,19 +440,18 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a 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.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 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/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= 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= @@ -539,18 +483,18 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/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/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 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 v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -573,6 +517,7 @@ 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/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -580,24 +525,30 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= 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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.4 h1:uGy6JWR/uMIILU8wbf+OkstIrNiMjGpEIyhx8f6W7s4= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.10.0 h1:ebSgKfMxynOdxw8QQuFOKMgomqeLGPqNLQox2bo42zg= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= 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/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= 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/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= @@ -619,7 +570,6 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z 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/gorilla/websocket v1.4.2/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= @@ -627,11 +577,10 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de 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/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 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= @@ -648,9 +597,8 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1: github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= -github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.3 h1:5n2R5B7+2YWrtEzIWO2jPPQWseAPLkgIuvUgS1l97KY= +github.com/hashicorp/go-retryablehttp v0.7.3/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= 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= @@ -663,8 +611,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 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.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 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= @@ -681,13 +629,13 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: 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.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/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/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI= -github.com/infobloxopen/infoblox-go-client/v2 v2.1.2-0.20220407114022-6f4c71443168 h1:EXKtVoP/44ckXpw3v2/vrtMEdKx/PA+YBl+REoV27XQ= -github.com/infobloxopen/infoblox-go-client/v2 v2.1.2-0.20220407114022-6f4c71443168/go.mod h1:+lznx4ASBSUZ2i6qwlgyn0v3eKDxBHNU5aRJzghAFbw= +github.com/infobloxopen/infoblox-go-client/v2 v2.3.0 h1:xLHcstumFvziz8dhrc+8gNRwfAyM2Q0nLSlyfK0+3XU= +github.com/infobloxopen/infoblox-go-client/v2 v2.3.0/go.mod h1:ZR191VH7ccpUZ+dzjALQorTevLPv+1P9N62TGJ87ib0= +github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= @@ -715,14 +663,12 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 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.11/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= @@ -731,10 +677,7 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY 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/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= 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= @@ -742,39 +685,28 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +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/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A= -github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= -github.com/lestrrat-go/codegen v1.0.2/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM= -github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE= -github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= -github.com/lestrrat-go/jwx v1.2.7/go.mod h1:bw24IXWbavc0R2RsOtpXL7RtMyP589yZ1+L7kd09ZGA= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 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= @@ -784,38 +716,33 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b 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/linode/linodego v1.9.1 h1:29UpEPpYcGFnbwiJW8mbk/bjBZpgd/pv68io2IKTo34= -github.com/linode/linodego v1.9.1/go.mod h1:h6AuFR/JpqwwM/vkj7s8KV3iGN8/jxn+zc437F8SZ8w= +github.com/linode/linodego v1.17.0 h1:aWS98f0jUoY2lhsEuBxRdVkqyGM0nazPd68AEDF0EvU= +github.com/linode/linodego v1.17.0/go.mod h1:/omzPxie0/YI6S0sTw1q47qDt5IYSlbO/infRR4UG+A= 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/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +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/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= 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-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 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-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= 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= @@ -824,20 +751,17 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh 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/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= -github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= -github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/maxatome/go-testdeep v1.13.0 h1:EBmRelH7MhMfPvA+0kXAeOeJUXn3mzul5NmvjLDcQZI= +github.com/maxatome/go-testdeep v1.13.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= 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/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= -github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= @@ -857,9 +781,6 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/protoc-gen-go-json v0.0.0-20190813154521-ece073100ced/go.mod h1:VhkV06JZBMrulb3fNiUvM5Lmz3yc7ei3omzocl9UtCw= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= 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= @@ -873,7 +794,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m 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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/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= @@ -906,23 +826,17 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W 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.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= 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.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= 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.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= @@ -937,12 +851,10 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X 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-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= -github.com/openshift/api v0.0.0-20210315202829-4b79815405ec h1:Uoyk1PiylPs99uuDpUiYyqjbk6BkZRj/oCJeQ2f3WSE= -github.com/openshift/api v0.0.0-20210315202829-4b79815405ec/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= -github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47 h1:+TEY29DK0XhqB7HFC9OfV8qf3wffSyi7MWv3AP28DGQ= -github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47/go.mod h1:u7NRAjtYVAKokiI9LouzTv4mhds8P4S1TwdVAfbjKSk= +github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= +github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/openshift/client-go v3.9.0+incompatible h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0= +github.com/openshift/client-go v3.9.0+incompatible/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b h1:it0YPE/evO6/m8t8wxis9KFI2F/aleOKsI6d9uz0cEk= github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b/go.mod h1:tNrEB5k8SI+g5kOlsCmL2ELASfpqEofI0+FLBgBdN08= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -955,10 +867,10 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/oracle/oci-go-sdk/v65 v65.35.0 h1:zvDsEuGs0qf6hPZVbrDnnfPJYQP7CwAgidTr4Pch6E4= -github.com/oracle/oci-go-sdk/v65 v65.35.0/go.mod h1:MXMLMzHnnd9wlpgadPkdlkZ9YrwQmCOmbX5kjVEJodw= -github.com/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk= -github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= +github.com/oracle/oci-go-sdk/v65 v65.41.0 h1:BTGVqeTo7gCp3ebVYxlm6ezhSLKl58E9hm3eTGN6M8M= +github.com/oracle/oci-go-sdk/v65 v65.41.0/go.mod h1:MXMLMzHnnd9wlpgadPkdlkZ9YrwQmCOmbX5kjVEJodw= +github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM= +github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M= 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= @@ -967,7 +879,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= 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/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 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/peterhellberg/link v1.1.0 h1:s2+RH8EGuI/mI4QwrWGSYQCRz7uNgip9BaM04HKu5kc= @@ -983,14 +896,15 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/pluralsh/gqlclient v1.1.6 h1:lj6KVfUET9DPyB95+T+hXtCGqqOm+TXOB3jYzuBX1Zc= -github.com/pluralsh/gqlclient v1.1.6/go.mod h1:qcE4KD7hBGl/JFCoXXy8zgUP0mWHJsAM6bhDAf592AE= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pluralsh/gqlclient v1.3.17 h1:hD/rG+lhxP3kN1UUXrzZd2uN7P76MvNTEJEzYOpERXo= +github.com/pluralsh/gqlclient v1.3.17/go.mod h1:z1qHnvPeqIN/a+5OzFs40e6HI6tDxzh1+yJuEpvqGy4= 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.23.2 h1:L7t1ghQJLjN3SaqJ/iOtp3VRpTebm0Y4XgQoS9ZUArc= -github.com/projectcontour/contour v1.23.2/go.mod h1:+ngF5UpPvS+ZpioG9XBY0hvtst47CjAWhOcLyEcXHHA= +github.com/projectcontour/contour v1.25.0 h1:Vdq//JTZfo52cxCddKVLCC6eWANrcHSg/U1HBRuUFro= +github.com/projectcontour/contour v1.25.0/go.mod h1:Nehnwg9lPUPqSUQEP1HwQt+HikkvTmZMs6AQ0mxHT+I= 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= @@ -998,11 +912,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf 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.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= 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= @@ -1010,8 +921,8 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: 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.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= 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= @@ -1019,11 +930,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 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.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us= +github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc= 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= @@ -1032,25 +940,20 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT 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.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= 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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 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.2.2/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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 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= @@ -1058,8 +961,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD 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/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f h1:WSnaD0/cvbKJgSTYbjAPf4RJXVvNNDAwVm+W8wEmnGE= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 h1:1WuWJu7/e8SqK+uQl7lfk/N/oMZTL2NE/TJsNKRNMc4= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/schollz/progressbar/v3 v3.8.6 h1:QruMUdzZ1TbEP++S1m73OqRJk20ON11m6Wqv4EoGg8c= github.com/schollz/progressbar/v3 v3.8.6/go.mod h1:W5IEwbJecncFGBvuEh4A7HT1nZZ6WNIL2i3qbnI0WKY= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -1069,25 +972,20 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 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.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.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +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/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= 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/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/gunit v1.0.4/go.mod h1:EH5qMBab2UclzXUcpR8b93eHsIlp9u+pDQIRp5DZNzQ= github.com/smartystreets/gunit v1.3.4 h1:iHc8Rfhb/uCOc9a3KGuD3ut22L+hLIVaqR1o5fS6zC4= github.com/smartystreets/gunit v1.3.4/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1097,14 +995,19 @@ github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ 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/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= 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/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 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/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1113,7 +1016,8 @@ 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/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= 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= @@ -1133,57 +1037,49 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +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/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.599 h1:9rMFA8++HynZHYz32gAluJ2ONtz7NjhlBaiomVHWwdw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.599/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.344 h1:pdwJ6T3iEjP5nB9Mgi4y/OBO8XNtkGN2/+mjGZ8yCbw= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.344/go.mod h1:CuOaLxOQr477GhMWAQPYQFUJrsZbW+ZqkAgP2uHDZXg= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.599 h1:VQqI9ln8dsCDCOleLvm8bR1/g8q8x2QIiMyzRLRrwWg= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.599/go.mod h1:GexzvtWfywrNN4h0+enS8iZBu2OeL6ArsSdcG1ScrwI= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682 h1:k00Y/PASfeb/ekWRK4RByIX/5guZ6o0lc3WNxIPq35o= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682 h1:AVIySVUzJw1XBoJd5C/g0tyXiTNRaWDrjUc16NMU4Ec= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682/go.mod h1:Ty5osmJagHfoO/7NQoddIsEmm1kzvnGoie1W9PQaaVo= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682 h1:dIWG/6zUfwo+kcFRID+ta6txig4UTskOfP7Tn2SXF0I= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682/go.mod h1:KPHBkCraRInvJ4xAkQcnzvqMU1d4VOXsF8gRAs8MEBQ= github.com/terra-farm/udnssdk v1.3.5 h1:MNR3adfuuEK/l04+jzo8WW/0fnorY+nW515qb3vEr6I= github.com/terra-farm/udnssdk v1.3.5/go.mod h1:8RnM56yZTR7mYyUIvrDgXzdRaEyFIzqdEi7+um26Sv8= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= 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/transip/gotransip/v6 v6.19.0 h1:L8MLCvebIst+NHRYrezupRda9NfyoINbY81CMlaWUGM= -github.com/transip/gotransip/v6 v6.19.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c= +github.com/transip/gotransip/v6 v6.20.0 h1:AuvwyOZ51f2brzMbTqlRy/wmaM3kF7Vx5Wds8xcDflY= +github.com/transip/gotransip/v6 v6.20.0/go.mod h1:nzv9eN2tdsUrm5nG5ZX6AugYIU4qgsMwIn2c0EZLk8c= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60 h1:n7unetnX8WWTc0U85h/0+dJoLWLqoaJwowXB9RkBdxU= -github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60/go.mod h1:43vmy6GEvRuVMpGEWfJ/JoEM6RIqUQI1/tb8JqZR1zI= +github.com/ultradns/ultradns-sdk-go v1.3.7 h1:P4CaM+npeXIybbLL27ezR316NnyILI1Y8IvfZtNE+Co= +github.com/ultradns/ultradns-sdk-go v1.3.7/go.mod h1:43vmy6GEvRuVMpGEWfJ/JoEM6RIqUQI1/tb8JqZR1zI= 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/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/vektah/gqlparser/v2 v2.5.0 h1:GwEwy7AJsqPWrey0bHnn+3JLaHLZVT66wY/+O+Tf9SU= -github.com/vektah/gqlparser/v2 v2.5.0/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= -github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 h1:UbVjBjgJUYGD8MlobEdOR+yTeNqaNa2Gf1/nskVNCSE= -github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg= +github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= +github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= +github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ= +github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 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= @@ -1205,19 +1101,16 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go 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/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.etcd.io/etcd/api/v3 v3.5.8 h1:Zf44zJszoU7zRV0X/nStPenegNXoFDWcB/MwrJbA+L4= -go.etcd.io/etcd/api/v3 v3.5.8/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= -go.etcd.io/etcd/client/pkg/v3 v3.5.8 h1:tPp9YRn/UBFAHdhOQUII9eUs7aOK35eulpMhX4YBd+M= -go.etcd.io/etcd/client/pkg/v3 v3.5.8/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= -go.etcd.io/etcd/client/v3 v3.5.8 h1:B6ngTKZSWWowHEoaucOKHQR/AtZKaoHLiUpWxOLG4l4= -go.etcd.io/etcd/client/v3 v3.5.8/go.mod h1:idZYIPVkttBJBiRigkB5EM0MmEyx8jcl18zCV3F5noc= +go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs= +go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= +go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE= +go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= +go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E= +go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= 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.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= @@ -1228,27 +1121,28 @@ 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.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 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/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= 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 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= 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.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= 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= @@ -1257,7 +1151,6 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf 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-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1267,22 +1160,19 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U 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-20200302210943-78000ba7a073/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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1305,6 +1195,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1313,13 +1204,12 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/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.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1363,40 +1253,40 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 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-20201031054903-ff519b6c9102/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= 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-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= 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-20190412183630-56d357773e84/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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1405,8 +1295,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.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= @@ -1423,15 +1313,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/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-20190507160741-ecd444e8653b/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-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1443,14 +1330,12 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1462,49 +1347,39 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/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.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1515,18 +1390,17 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.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.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/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= @@ -1539,18 +1413,13 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/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-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 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-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1559,7 +1428,6 @@ golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/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-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1580,27 +1448,27 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/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-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1624,8 +1492,11 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= 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= @@ -1660,16 +1531,27 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc h1:ijGwO+0vL2hJt5gaygqP2j6PfflOBrRot0IczKbmtio= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +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/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= @@ -1685,13 +1567,19 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +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.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.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/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= @@ -1705,8 +1593,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.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= @@ -1722,7 +1610,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy 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/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= @@ -1730,15 +1617,13 @@ gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdOD gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/ns1/ns1-go.v2 v2.7.4 h1:uLb8u8uM9E7Xij/GHPctVIKMwyQDcA8NjSPnScG7gmQ= -gopkg.in/ns1/ns1-go.v2 v2.7.4/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk= +gopkg.in/ns1/ns1-go.v2 v2.7.6 h1:mCPl7q0jbIGACXvGBljAuuApmKZo3rRi4tlRIEbMvjA= +gopkg.in/ns1/ns1-go.v2 v2.7.6/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= 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= @@ -1748,6 +1633,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN 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= @@ -1759,12 +1645,9 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= 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= @@ -1774,86 +1657,57 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -istio.io/api v0.0.0-20210128181506-0c4b8e54850f h1:zUFsawgPj5oI9p5cf91YCExRlxLIVsEkIunN9ODUSJs= -istio.io/api v0.0.0-20210128181506-0c4b8e54850f/go.mod h1:88HN3o1fSD1jo+Z1WTLlJfMm9biopur6Ct9BFKjiB64= -istio.io/client-go v0.0.0-20210128182905-ee2edd059e02 h1:ZA8Y2gKkKtEeYuKfqlEzIBDfU4IE5uIAdsXDeD41T9w= -istio.io/client-go v0.0.0-20210128182905-ee2edd059e02/go.mod h1:oXMjFUWhxlReUSbg4i3GjKgOhSX1WgD68ZNlHQEcmQg= +istio.io/api v0.0.0-20230524015941-fa6c5f7916bf h1:yY8r1TtMBaOTDaF2mEJ1LzXJbHdmN0HLiSL7TScpFEI= +istio.io/api v0.0.0-20230524015941-fa6c5f7916bf/go.mod h1:dDMe1TsOtrRoUlBzdxqNolWXpXPQjLfbcXvqPMtQ6eo= +istio.io/client-go v1.18.0 h1:T89Foio5RbQQakoJdGLk7e8fIvv5xTqLaRpG9Y3lfRE= +istio.io/client-go v1.18.0/go.mod h1:e/55rKUWBUuNc07GSN0DGYl1x0WflOBx+xVw7giWZhU= istio.io/gogo-genproto v0.0.0-20190904133402-ee07f2785480/go.mod h1:uKtbae4K9k2rjjX4ToV0l6etglbc1i7gqQ94XdkshzY= -istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE= -istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs= k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= -k8s.io/api v0.18.1/go.mod h1:3My4jorQWzSs5a+l7Ge6JBbIxChLnY8HnuT58ZWolss= 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.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= -k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= -k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= -k8s.io/api v0.26.0 h1:IpPlZnxBpV1xl7TGk/X6lFtpgjgntCg8PJ+qrPHAC7I= -k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= +k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= +k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= 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.20.4/go.mod h1:Hzebis/9c6Io5yzHp24Vg4XOkTp1ViMwKP/6gmpsfA4= -k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.18.1/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.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= -k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= -k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= +k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= 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/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= -k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw= 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.1/go.mod h1:iCikYRiXOj/yRRFE/aWqrpPtDt4P2JVWhtHkmESTcfY= 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.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= -k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= -k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= -k8s.io/client-go v0.26.0 h1:lT1D3OfO+wIi9UFolCrifbjUUgu7CpLca0AD8ghRLI8= -k8s.io/client-go v0.26.0/go.mod h1:I2Sh57A79EQsDmn7F7ASpmru1cceh3ocVT9KlX2jEZg= +k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= +k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48= 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/code-generator v0.20.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/code-generator v0.20.4/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= 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.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= -k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc= 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/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= 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/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-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= 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-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= +k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1861,21 +1715,17 @@ rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= -sigs.k8s.io/controller-runtime v0.12.1 h1:4BJY01xe9zKQti8oRjj/NeHKRXthf1YkYJAgLONFFoI= -sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXez/vp1Y8dxTU0= +sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= +sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/controller-tools v0.3.1-0.20200517180335-820a4a27ea84/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= -sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= -sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +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.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= From c2b11484d32f91925ceb3e6bccffbbf19ae19ff5 Mon Sep 17 00:00:00 2001 From: jongwooo Date: Sat, 17 Jun 2023 00:06:52 +0900 Subject: [PATCH 125/154] Replace deprecated command with environment file --- .github/workflows/lint-test-chart.yaml | 2 +- .github/workflows/release-chart.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-test-chart.yaml b/.github/workflows/lint-test-chart.yaml index 2f6025cf08..2b6b5b13a9 100644 --- a/.github/workflows/lint-test-chart.yaml +++ b/.github/workflows/lint-test-chart.yaml @@ -45,7 +45,7 @@ jobs: run: | changed=$(ct list-changed) if [[ -n "$changed" ]]; then - echo "::set-output name=changed::true" + echo "changed=true" >> $GITHUB_OUTPUT fi - name: Run chart-testing (lint) diff --git a/.github/workflows/release-chart.yaml b/.github/workflows/release-chart.yaml index 95ce0baa85..770e9a04a2 100644 --- a/.github/workflows/release-chart.yaml +++ b/.github/workflows/release-chart.yaml @@ -29,7 +29,7 @@ jobs: run: | set -euo pipefail chart_version="$(grep -Po "(?<=^version: ).+" charts/external-dns/Chart.yaml)" - echo "::set-output name=version::${chart_version}" + echo "version=${chart_version}" >> $GITHUB_OUTPUT - name: Get changelog entry id: changelog_reader From e06ed8cc5d30a299f5d13623cf93f631ed013e5a Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Fri, 16 Jun 2023 17:15:35 +0200 Subject: [PATCH 126/154] build(deps): bump dev-dependencies group with 40 updates --- .github/workflows/lint.yaml | 4 ++-- .golangci.yml | 8 +++++++ go.mod | 13 ++++------- go.sum | 28 +++++++++++------------ provider/cloudflare/cloudflare.go | 28 ++++++++++++++++------- provider/cloudflare/cloudflare_test.go | 6 ++--- provider/ibmcloud/ibmcloud.go | 22 +++++++++--------- provider/infoblox/infoblox.go | 20 ++++++---------- provider/infoblox/infoblox_test.go | 20 ++++++---------- provider/rfc2136/rfc2136.go | 1 - provider/tencentcloud/cloudapi/mockapi.go | 17 ++++++-------- source/istio_gateway.go | 14 ++++++------ source/istio_gateway_test.go | 6 ++--- source/istio_virtualservice_test.go | 10 ++++---- source/openshift_route.go | 3 ++- source/source.go | 6 ++--- 16 files changed, 104 insertions(+), 102 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 58465ce1fa..9feb49b72f 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -23,7 +23,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: 1.20 id: go - name: Check out code into the Go module directory @@ -31,5 +31,5 @@ jobs: - name: Lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.2 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.53.3 make lint diff --git a/.golangci.yml b/.golangci.yml index e5a24cf6a9..da6227d28a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -60,6 +60,14 @@ issues: - unused - varcheck - whitespace + - path: source/ambassador_host.go + linters: [ typecheck ] + - path: source/contour_httpproxy.go + linters: [ typecheck ] + - path: source/f5_virtualserver.go + linters: [ typecheck ] + - path: source/kong_tcpingress.go + linters: [ typecheck ] run: skip-files: diff --git a/go.mod b/go.mod index 7d5b70a146..ad8f487b06 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/nic-at/rc0go v1.1.1 github.com/onsi/ginkgo v1.16.5 github.com/openshift/api v3.9.0+incompatible - github.com/openshift/client-go v3.9.0+incompatible + github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3 github.com/oracle/oci-go-sdk/v65 v65.41.0 github.com/ovh/go-ovh v1.4.1 github.com/pkg/errors v0.9.1 @@ -70,9 +70,9 @@ require ( gopkg.in/yaml.v2 v2.4.0 istio.io/api v0.0.0-20230524015941-fa6c5f7916bf istio.io/client-go v1.18.0 - k8s.io/api v0.27.3 - k8s.io/apimachinery v0.27.3 - k8s.io/client-go v0.27.3 + k8s.io/api v0.27.2 + k8s.io/apimachinery v0.27.2 + k8s.io/client-go v0.27.2 sigs.k8s.io/gateway-api v0.7.1 ) @@ -115,7 +115,6 @@ require ( github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect @@ -205,12 +204,10 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect - k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect + k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect moul.io/http2curl v1.0.0 // indirect sigs.k8s.io/controller-runtime v0.14.6 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) - -replace k8s.io/klog/v2 => github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a diff --git a/go.sum b/go.sum index 72077643c7..3e55d4233f 100644 --- a/go.sum +++ b/go.sum @@ -105,8 +105,6 @@ github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt 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/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a h1:4D87FDUGSrfLp/NJmYxybiC8+OR8s5eULyNgmmxAI9U= -github.com/Raffo/knolog v0.0.0-20211016155154-e4d5e0cc970a/go.mod h1:AsBYmtPY5rgsIyjQZDLO+Dwdx91Jmi6uxu7LO6Xf9iw= 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= @@ -344,6 +342,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 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.3/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= @@ -450,8 +449,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w 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/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= 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= @@ -853,8 +850,8 @@ github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.m github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/client-go v3.9.0+incompatible h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0= -github.com/openshift/client-go v3.9.0+incompatible/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= +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/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b h1:it0YPE/evO6/m8t8wxis9KFI2F/aleOKsI6d9uz0cEk= github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b/go.mod h1:tNrEB5k8SI+g5kOlsCmL2ELASfpqEofI0+FLBgBdN08= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1665,16 +1662,16 @@ istio.io/gogo-genproto v0.0.0-20190904133402-ee07f2785480/go.mod h1:uKtbae4K9k2r 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.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= -k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= +k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= +k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= 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/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.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= -k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= +k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= 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= @@ -1683,8 +1680,8 @@ 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.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= -k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48= +k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= +k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= 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= @@ -1697,6 +1694,9 @@ k8s.io/helm v2.16.9+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg 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-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= @@ -1706,8 +1706,8 @@ k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= 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-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= +k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/provider/cloudflare/cloudflare.go b/provider/cloudflare/cloudflare.go index 0623ca2a05..f6bc950458 100644 --- a/provider/cloudflare/cloudflare.go +++ b/provider/cloudflare/cloudflare.go @@ -69,7 +69,7 @@ type cloudFlareDNS interface { ListZonesContext(ctx context.Context, opts ...cloudflare.ReqOption) (cloudflare.ZonesResponse, error) ZoneDetails(ctx context.Context, zoneID string) (cloudflare.Zone, error) ListDNSRecords(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.ListDNSRecordsParams) ([]cloudflare.DNSRecord, *cloudflare.ResultInfo, error) - CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (*cloudflare.DNSRecordResponse, error) + CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (cloudflare.DNSRecord, error) DeleteDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, recordID string) error UpdateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.UpdateDNSRecordParams) error } @@ -90,7 +90,7 @@ func (z zoneService) ZoneIDByName(zoneName string) (string, error) { return z.service.ZoneIDByName(zoneName) } -func (z zoneService) CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (*cloudflare.DNSRecordResponse, error) { +func (z zoneService) CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (cloudflare.DNSRecord, error) { return z.service.CreateDNSRecord(ctx, rc, rp) } @@ -99,7 +99,8 @@ func (z zoneService) ListDNSRecords(ctx context.Context, rc *cloudflare.Resource } func (z zoneService) UpdateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.UpdateDNSRecordParams) error { - return z.service.UpdateDNSRecord(ctx, rc, rp) + _, err := z.service.UpdateDNSRecord(ctx, rc, rp) + return err } func (z zoneService) DeleteDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, recordID string) error { @@ -137,9 +138,20 @@ type RecordParamsTypes interface { cloudflare.UpdateDNSRecordParams | cloudflare.CreateDNSRecordParams } -// getRecordParam is a generic function that returns the appropriate Record Param based on the cloudFlareChange passed in -func getRecordParam[T RecordParamsTypes](cfc cloudFlareChange) T { - return T{ +// getUpdateDNSRecordParam is a function that returns the appropriate Record Param based on the cloudFlareChange passed in +func getUpdateDNSRecordParam(cfc cloudFlareChange) cloudflare.UpdateDNSRecordParams { + return cloudflare.UpdateDNSRecordParams{ + Name: cfc.ResourceRecord.Name, + TTL: cfc.ResourceRecord.TTL, + Proxied: cfc.ResourceRecord.Proxied, + Type: cfc.ResourceRecord.Type, + Content: cfc.ResourceRecord.Content, + } +} + +// getCreateDNSRecordParam is a function that returns the appropriate Record Param based on the cloudFlareChange passed in +func getCreateDNSRecordParam(cfc cloudFlareChange) cloudflare.CreateDNSRecordParams { + return cloudflare.CreateDNSRecordParams{ Name: cfc.ResourceRecord.Name, TTL: cfc.ResourceRecord.TTL, Proxied: cfc.ResourceRecord.Proxied, @@ -334,7 +346,7 @@ func (p *CloudFlareProvider) submitChanges(ctx context.Context, changes []*cloud log.WithFields(logFields).Errorf("failed to find previous record: %v", change.ResourceRecord) continue } - recordParam := getRecordParam[cloudflare.UpdateDNSRecordParams](*change) + recordParam := getUpdateDNSRecordParam(*change) recordParam.ID = recordID err := p.Client.UpdateDNSRecord(ctx, resourceContainer, recordParam) if err != nil { @@ -351,7 +363,7 @@ func (p *CloudFlareProvider) submitChanges(ctx context.Context, changes []*cloud log.WithFields(logFields).Errorf("failed to delete record: %v", err) } } else if change.Action == cloudFlareCreate { - recordParam := getRecordParam[cloudflare.CreateDNSRecordParams](*change) + recordParam := getCreateDNSRecordParam(*change) _, err := p.Client.CreateDNSRecord(ctx, resourceContainer, recordParam) if err != nil { log.WithFields(logFields).Errorf("failed to create record: %v", err) diff --git a/provider/cloudflare/cloudflare_test.go b/provider/cloudflare/cloudflare_test.go index 6d1d47b400..5040404d23 100644 --- a/provider/cloudflare/cloudflare_test.go +++ b/provider/cloudflare/cloudflare_test.go @@ -130,7 +130,7 @@ func getDNSRecordFromRecordParams(rp any) cloudflare.DNSRecord { } } -func (m *mockCloudFlareClient) CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (*cloudflare.DNSRecordResponse, error) { +func (m *mockCloudFlareClient) CreateDNSRecord(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.CreateDNSRecordParams) (cloudflare.DNSRecord, error) { recordData := getDNSRecordFromRecordParams(rp) m.Actions = append(m.Actions, MockAction{ Name: "Create", @@ -141,7 +141,7 @@ func (m *mockCloudFlareClient) CreateDNSRecord(ctx context.Context, rc *cloudfla if zone, ok := m.Records[rc.Identifier]; ok { zone[rp.ID] = recordData } - return nil, nil + return cloudflare.DNSRecord{}, nil } func (m *mockCloudFlareClient) ListDNSRecords(ctx context.Context, rc *cloudflare.ResourceContainer, rp cloudflare.ListDNSRecordsParams) ([]cloudflare.DNSRecord, *cloudflare.ResultInfo, error) { @@ -680,7 +680,7 @@ func TestCloudflareProvider(t *testing.T) { _ = os.Unsetenv("CF_API_TOKEN") tokenFile := "/tmp/cf_api_token" - if err := os.WriteFile(tokenFile, []byte("abc123def"), 0644); err != nil { + if err := os.WriteFile(tokenFile, []byte("abc123def"), 0o644); err != nil { t.Errorf("failed to write token file, %s", err) } _ = os.Setenv("CF_API_TOKEN", tokenFile) diff --git a/provider/ibmcloud/ibmcloud.go b/provider/ibmcloud/ibmcloud.go index 1340edfd2c..c8560db013 100644 --- a/provider/ibmcloud/ibmcloud.go +++ b/provider/ibmcloud/ibmcloud.go @@ -757,7 +757,7 @@ func (p *IBMCloudProvider) groupPrivateRecords(records []dnssvcsv1.ResourceRecor for _, records := range groups { targets := make([]string, len(records)) for i, record := range records { - data := record.Rdata.(map[string]interface{}) + data := record.Rdata log.Debugf("record data: %v", data) switch *record.Type { case "A": @@ -820,18 +820,18 @@ func (p *IBMCloudProvider) newIBMCloudChange(action string, endpoint *endpoint.E } if p.privateZone { - var rData interface{} + rData := make(map[string]interface{}) switch endpoint.RecordType { case "A": - rData = &dnssvcsv1.ResourceRecordInputRdataRdataARecord{ + rData[dnssvcsv1.CreateResourceRecordOptions_Type_A] = &dnssvcsv1.ResourceRecordInputRdataRdataARecord{ Ip: core.StringPtr(target), } case "CNAME": - rData = &dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord{ + rData[dnssvcsv1.CreateResourceRecordOptions_Type_Cname] = &dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord{ Cname: core.StringPtr(target), } case "TXT": - rData = &dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord{ + rData[dnssvcsv1.CreateResourceRecordOptions_Type_Txt] = &dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord{ Text: core.StringPtr(target), } } @@ -869,15 +869,15 @@ func (p *IBMCloudProvider) createRecord(ctx context.Context, zoneID string, chan } switch *change.PrivateResourceRecord.Type { case "A": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataARecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_A].(*dnssvcsv1.ResourceRecordInputRdataRdataARecord) aData, _ := p.Client.NewResourceRecordInputRdataRdataARecord(*data.Ip) createResourceRecordOptions.SetRdata(aData) case "CNAME": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_Cname].(*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord) cnameData, _ := p.Client.NewResourceRecordInputRdataRdataCnameRecord(*data.Cname) createResourceRecordOptions.SetRdata(cnameData) case "TXT": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_Txt].(*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord) txtData, _ := p.Client.NewResourceRecordInputRdataRdataTxtRecord(*data.Text) createResourceRecordOptions.SetRdata(txtData) } @@ -910,15 +910,15 @@ func (p *IBMCloudProvider) updateRecord(ctx context.Context, zoneID, recordID st } switch *change.PrivateResourceRecord.Type { case "A": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataARecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_A].(*dnssvcsv1.ResourceRecordInputRdataRdataARecord) aData, _ := p.Client.NewResourceRecordUpdateInputRdataRdataARecord(*data.Ip) updateResourceRecordOptions.SetRdata(aData) case "CNAME": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_Cname].(*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord) cnameData, _ := p.Client.NewResourceRecordUpdateInputRdataRdataCnameRecord(*data.Cname) updateResourceRecordOptions.SetRdata(cnameData) case "TXT": - data, _ := change.PrivateResourceRecord.Rdata.(*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord) + data, _ := change.PrivateResourceRecord.Rdata[dnssvcsv1.CreateResourceRecordOptions_Type_Txt].(*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord) txtData, _ := p.Client.NewResourceRecordUpdateInputRdataRdataTxtRecord(*data.Text) updateResourceRecordOptions.SetRdata(txtData) } diff --git a/provider/infoblox/infoblox.go b/provider/infoblox/infoblox.go index bea9321667..0286eb7ebc 100644 --- a/provider/infoblox/infoblox.go +++ b/provider/infoblox/infoblox.go @@ -307,12 +307,9 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End } var resT []ibclient.RecordTXT - objT := ibclient.NewRecordTXT( - ibclient.RecordTXT{ - Zone: zone.Fqdn, - View: p.view, - }, - ) + objT := ibclient.NewEmptyRecordTXT() + objT.Zone = zone.Fqdn + objT.View = p.view err = p.client.GetObject(objT, "", searchParams, &resT) if err != nil && !isNotFoundError(err) { return nil, fmt.Errorf("could not fetch TXT records from zone '%s': %w", zone.Fqdn, err) @@ -603,13 +600,10 @@ func (p *ProviderConfig) recordSet(ep *endpoint.Endpoint, getObject bool, target if target, err2 := strconv.Unquote(ep.Targets[0]); err2 == nil && !strings.Contains(ep.Targets[0], " ") { ep.Targets = endpoint.Targets{target} } - obj := ibclient.NewRecordTXT( - ibclient.RecordTXT{ - Name: ep.DNSName, - Text: ep.Targets[0], - View: p.view, - }, - ) + obj := ibclient.NewEmptyRecordTXT() + obj.Name = ep.DNSName + obj.Text = ep.Targets[0] + obj.View = p.view if getObject { queryParams := ibclient.NewQueryParams(false, map[string]string{"name": obj.Name}) err = p.client.GetObject(obj, "", queryParams, &res) diff --git a/provider/infoblox/infoblox_test.go b/provider/infoblox/infoblox_test.go index 13b5e0b52e..9dc3ed4163 100644 --- a/provider/infoblox/infoblox_test.go +++ b/provider/infoblox/infoblox_test.go @@ -254,11 +254,8 @@ func (client *mockIBConnector) DeleteObject(ref string) (refRes string, err erro } case "record:txt": var records []ibclient.RecordTXT - obj := ibclient.NewRecordTXT( - ibclient.RecordTXT{ - Name: result[2], - }, - ) + obj := ibclient.NewEmptyRecordTXT() + obj.Name = result[2] client.GetObject(obj, ref, nil, &records) for _, record := range records { client.deletedEndpoints = append( @@ -355,13 +352,11 @@ func createMockInfobloxObject(name, recordType, value string) ibclient.IBObject obj.Canonical = value return obj case endpoint.RecordTypeTXT: - return ibclient.NewRecordTXT( - ibclient.RecordTXT{ - Ref: ref, - Name: name, - Text: value, - }, - ) + obj := ibclient.NewEmptyRecordTXT() + obj.Name = name + obj.Ref = ref + obj.Text = value + return obj case "HOST": obj := ibclient.NewEmptyHostRecord() obj.Name = name @@ -738,7 +733,6 @@ func TestExtendedRequestNameRegExBuilder(t *testing.T) { assert.True(t, req.URL.Query().Get("name~") == "") } - func TestExtendedRequestMaxResultsBuilder(t *testing.T) { hostCfg := ibclient.HostConfig{ Host: "localhost", diff --git a/provider/rfc2136/rfc2136.go b/provider/rfc2136/rfc2136.go index b46e410337..54a5211a4b 100644 --- a/provider/rfc2136/rfc2136.go +++ b/provider/rfc2136/rfc2136.go @@ -389,7 +389,6 @@ func (r rfc2136Provider) SendMessage(msg *dns.Msg) error { log.Debugf("SendMessage") c := new(dns.Client) - c.SingleInflight = true if !r.insecure { if r.gssTsig { diff --git a/provider/tencentcloud/cloudapi/mockapi.go b/provider/tencentcloud/cloudapi/mockapi.go index 707579f008..3484ddc120 100644 --- a/provider/tencentcloud/cloudapi/mockapi.go +++ b/provider/tencentcloud/cloudapi/mockapi.go @@ -135,11 +135,12 @@ func (api *mockAPIService) DescribePrivateZoneRecordList(request *privatedns.Des func (api *mockAPIService) DescribeDomainList(request *dnspod.DescribeDomainListRequest) (response *dnspod.DescribeDomainListResponse, err error) { response = dnspod.NewDescribeDomainListResponse() - response.Response = &struct { - DomainCountInfo *dnspod.DomainCountInfo `json:"DomainCountInfo,omitempty" name:"DomainCountInfo"` - DomainList []*dnspod.DomainListItem `json:"DomainList,omitempty" name:"DomainList"` - RequestId *string `json:"RequestId,omitempty" name:"RequestId"` - }{} + response.Response = &dnspod.DescribeDomainListResponseParams{ + DomainCountInfo: &dnspod.DomainCountInfo{ + AllTotal: common.Uint64Ptr(uint64(len(api.dnspodDomains))), + }, + DomainList: api.dnspodDomains, + } response.Response.DomainList = api.dnspodDomains response.Response.DomainCountInfo = &dnspod.DomainCountInfo{ AllTotal: common.Uint64Ptr(uint64(len(api.dnspodDomains))), @@ -149,11 +150,7 @@ func (api *mockAPIService) DescribeDomainList(request *dnspod.DescribeDomainList func (api *mockAPIService) DescribeRecordList(request *dnspod.DescribeRecordListRequest) (response *dnspod.DescribeRecordListResponse, err error) { response = dnspod.NewDescribeRecordListResponse() - response.Response = &struct { - RecordCountInfo *dnspod.RecordCountInfo `json:"RecordCountInfo,omitempty" name:"RecordCountInfo"` - RecordList []*dnspod.RecordListItem `json:"RecordList,omitempty" name:"RecordList"` - RequestId *string `json:"RequestId,omitempty" name:"RequestId"` - }{} + response.Response = &dnspod.DescribeRecordListResponseParams{} if _, exist := api.dnspodRecords[*request.Domain]; !exist { response.Response.RecordList = make([]*dnspod.RecordListItem, 0) response.Response.RecordCountInfo = &dnspod.RecordCountInfo{ diff --git a/source/istio_gateway.go b/source/istio_gateway.go index 4f5a68ddf9..76c1094cf4 100644 --- a/source/istio_gateway.go +++ b/source/istio_gateway.go @@ -149,7 +149,7 @@ func (sc *gatewaySource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e // apply template if host is missing on gateway if (sc.combineFQDNAnnotation || len(gwHostnames) == 0) && sc.fqdnTemplate != nil { - iHostnames, err := execTemplate(sc.fqdnTemplate, &gateway) + iHostnames, err := execTemplate(sc.fqdnTemplate, gateway) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (sc *gatewaySource) AddEventHandler(ctx context.Context, handler func()) { } // filterByAnnotations filters a list of configs by a given annotation selector. -func (sc *gatewaySource) filterByAnnotations(gateways []networkingv1alpha3.Gateway) ([]networkingv1alpha3.Gateway, error) { +func (sc *gatewaySource) filterByAnnotations(gateways []*networkingv1alpha3.Gateway) ([]*networkingv1alpha3.Gateway, error) { labelSelector, err := metav1.ParseToLabelSelector(sc.annotationFilter) if err != nil { return nil, err @@ -211,7 +211,7 @@ func (sc *gatewaySource) filterByAnnotations(gateways []networkingv1alpha3.Gatew return gateways, nil } - var filteredList []networkingv1alpha3.Gateway + var filteredList []*networkingv1alpha3.Gateway for _, gw := range gateways { // convert the annotations to an equivalent label selector @@ -226,13 +226,13 @@ func (sc *gatewaySource) filterByAnnotations(gateways []networkingv1alpha3.Gatew return filteredList, nil } -func (sc *gatewaySource) setResourceLabel(gateway networkingv1alpha3.Gateway, endpoints []*endpoint.Endpoint) { +func (sc *gatewaySource) setResourceLabel(gateway *networkingv1alpha3.Gateway, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("gateway/%s/%s", gateway.Namespace, gateway.Name) } } -func (sc *gatewaySource) targetsFromGateway(gateway networkingv1alpha3.Gateway) (targets endpoint.Targets, err error) { +func (sc *gatewaySource) targetsFromGateway(gateway *networkingv1alpha3.Gateway) (targets endpoint.Targets, err error) { targets = getTargetsFromTargetAnnotation(gateway.Annotations) if len(targets) > 0 { return @@ -262,7 +262,7 @@ func (sc *gatewaySource) targetsFromGateway(gateway networkingv1alpha3.Gateway) } // endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object -func (sc *gatewaySource) endpointsFromGateway(hostnames []string, gateway networkingv1alpha3.Gateway) ([]*endpoint.Endpoint, error) { +func (sc *gatewaySource) endpointsFromGateway(hostnames []string, gateway *networkingv1alpha3.Gateway) ([]*endpoint.Endpoint, error) { var endpoints []*endpoint.Endpoint annotations := gateway.Annotations @@ -289,7 +289,7 @@ func (sc *gatewaySource) endpointsFromGateway(hostnames []string, gateway networ return endpoints, nil } -func (sc *gatewaySource) hostNamesFromGateway(gateway networkingv1alpha3.Gateway) ([]string, error) { +func (sc *gatewaySource) hostNamesFromGateway(gateway *networkingv1alpha3.Gateway) ([]string, error) { var hostnames []string for _, server := range gateway.Spec.Servers { for _, host := range server.Hosts { diff --git a/source/istio_gateway_test.go b/source/istio_gateway_test.go index 535972a34b..ebbabd0bbd 100644 --- a/source/istio_gateway_test.go +++ b/source/istio_gateway_test.go @@ -1192,7 +1192,7 @@ func testGatewayEndpoints(t *testing.T) { fakeIstioClient := istiofake.NewSimpleClientset() for _, config := range ti.configItems { gatewayCfg := config.Config() - _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(ti.targetNamespace).Create(context.Background(), &gatewayCfg, metav1.CreateOptions{}) + _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(ti.targetNamespace).Create(context.Background(), gatewayCfg, metav1.CreateOptions{}) require.NoError(t, err) } @@ -1301,7 +1301,7 @@ type fakeGatewayConfig struct { selector map[string]string } -func (c fakeGatewayConfig) Config() networkingv1alpha3.Gateway { +func (c fakeGatewayConfig) Config() *networkingv1alpha3.Gateway { gw := networkingv1alpha3.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: c.name, @@ -1323,5 +1323,5 @@ func (c fakeGatewayConfig) Config() networkingv1alpha3.Gateway { gw.Spec.Servers = servers - return gw + return &gw } diff --git a/source/istio_virtualservice_test.go b/source/istio_virtualservice_test.go index a510094e75..63103fb725 100644 --- a/source/istio_virtualservice_test.go +++ b/source/istio_virtualservice_test.go @@ -71,7 +71,7 @@ func (suite *VirtualServiceSuite) SetupTest() { suite.NoError(err, "should succeed") } - suite.gwconfig = (fakeGatewayConfig{ + suite.gwconfig = *(fakeGatewayConfig{ name: "foo-gateway-with-targets", namespace: "istio-system", dnsnames: [][]string{{"*"}}, @@ -362,7 +362,7 @@ func testVirtualServiceBindsToGateway(t *testing.T) { t.Run(ti.title, func(t *testing.T) { vsconfig := ti.vsconfig.Config() gwconfig := ti.gwconfig.Config() - require.Equal(t, ti.expected, virtualServiceBindsToGateway(vsconfig, &gwconfig, ti.vsHost)) + require.Equal(t, ti.expected, virtualServiceBindsToGateway(vsconfig, gwconfig, ti.vsHost)) }) } } @@ -1479,7 +1479,7 @@ func testVirtualServiceEndpoints(t *testing.T) { t.Run(ti.title, func(t *testing.T) { t.Parallel() - var gateways []networkingv1alpha3.Gateway + var gateways []*networkingv1alpha3.Gateway var virtualservices []*networkingv1alpha3.VirtualService for _, gwItem := range ti.gwConfigs { @@ -1500,7 +1500,7 @@ func testVirtualServiceEndpoints(t *testing.T) { fakeIstioClient := istiofake.NewSimpleClientset() for _, gateway := range gateways { - _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gateway.Namespace).Create(context.Background(), &gateway, metav1.CreateOptions{}) + _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gateway.Namespace).Create(context.Background(), gateway, metav1.CreateOptions{}) require.NoError(t, err) } @@ -1579,7 +1579,7 @@ func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, g for _, gw := range gwList { gwObj := gw.Config() - _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), &gwObj, metav1.CreateOptions{}) + _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), gwObj, metav1.CreateOptions{}) if err != nil { return nil, err } diff --git a/source/openshift_route.go b/source/openshift_route.go index ec061c108b..14e0b632c8 100644 --- a/source/openshift_route.go +++ b/source/openshift_route.go @@ -21,6 +21,7 @@ import ( "fmt" "sort" "text/template" + "time" routev1 "github.com/openshift/api/route/v1" versioned "github.com/openshift/client-go/route/clientset/versioned" @@ -71,7 +72,7 @@ func NewOcpRouteSource( // Use a shared informer to listen for add/update/delete of Routes in the specified namespace. // Set resync period to 0, to prevent processing when nothing has changed. - informerFactory := extInformers.NewSharedInformerFactoryWithOptions(ocpClient, 0, extInformers.WithNamespace(namespace)) + informerFactory := extInformers.NewFilteredSharedInformerFactory(ocpClient, 0*time.Second, namespace, nil) informer := informerFactory.Route().V1().Routes() // Add default resource event handlers to properly initialize informer. diff --git a/source/source.go b/source/source.go index 5e3cdcf780..cf43ac4656 100644 --- a/source/source.go +++ b/source/source.go @@ -338,9 +338,9 @@ func matchLabelSelector(selector labels.Selector, srcAnnotations map[string]stri type eventHandlerFunc func() -func (fn eventHandlerFunc) OnAdd(obj interface{}) { fn() } -func (fn eventHandlerFunc) OnUpdate(oldObj, newObj interface{}) { fn() } -func (fn eventHandlerFunc) OnDelete(obj interface{}) { fn() } +func (fn eventHandlerFunc) OnAdd(obj interface{}, isInInitialList bool) { fn() } +func (fn eventHandlerFunc) OnUpdate(oldObj, newObj interface{}) { fn() } +func (fn eventHandlerFunc) OnDelete(obj interface{}) { fn() } type informerFactory interface { WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool From 04cb58dede01071e6b4f3b03cedece8ae7f017d3 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Fri, 16 Jun 2023 21:03:42 +0200 Subject: [PATCH 127/154] fix go version on lint --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 9feb49b72f..b5dd025095 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -23,7 +23,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: 1.20 + go-version: '1.20' id: go - name: Check out code into the Go module directory From d4fecf7eb5dba5d6704e83e73106ad9ffad3e6b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:19:22 +0000 Subject: [PATCH 128/154] build(deps): bump the dev-dependencies group with 1 update Bumps the dev-dependencies group with 1 update: [actions/setup-go](https://github.com/actions/setup-go). - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index cadcb0488f..df29ff6d33 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,7 +28,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - name: Install go version - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: '^1.20' From 66a770c5b8c4f5d5d78d13af081d9ca809776e72 Mon Sep 17 00:00:00 2001 From: Nick Revin Date: Sat, 17 Jun 2023 08:10:20 +0400 Subject: [PATCH 129/154] feat(chart): comply with Pod Security Standards (#3689) * feat(chart): comply with Pod Security Standards * chore(chart): Update CHANGELOG.md * chore(chart): add ci-values.yaml --- charts/external-dns/CHANGELOG.md | 2 ++ charts/external-dns/ci/ci-values.yaml | 1 + charts/external-dns/values.yaml | 3 +++ 3 files changed, 6 insertions(+) create mode 100644 charts/external-dns/ci/ci-values.yaml diff --git a/charts/external-dns/CHANGELOG.md b/charts/external-dns/CHANGELOG.md index 83f322a984..a8617cd6bb 100644 --- a/charts/external-dns/CHANGELOG.md +++ b/charts/external-dns/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### All Changes +- Disallowed privilege escalation in container security context and set the seccomp profile type to `RuntimeDefault`. ([#3689](https://github.com/kubernetes-sigs/external-dns/pull/3689)) [@nrvnrvn](https://github.com/nrvnrvn) + ## [v1.13.0] - 2023-03-30 ### All Changes diff --git a/charts/external-dns/ci/ci-values.yaml b/charts/external-dns/ci/ci-values.yaml new file mode 100644 index 0000000000..6c1735cbac --- /dev/null +++ b/charts/external-dns/ci/ci-values.yaml @@ -0,0 +1 @@ +provider: inmemory diff --git a/charts/external-dns/values.yaml b/charts/external-dns/values.yaml index 6e0f80265a..fe0f0dd4cb 100644 --- a/charts/external-dns/values.yaml +++ b/charts/external-dns/values.yaml @@ -43,8 +43,11 @@ shareProcessNamespace: false podSecurityContext: fsGroup: 65534 + seccompProfile: + type: RuntimeDefault securityContext: + allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 65534 readOnlyRootFilesystem: true From 4dd3de68e71c7454487a1c605b08ec3f328f2067 Mon Sep 17 00:00:00 2001 From: rumstead <37445536+rumstead@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:45:26 -0400 Subject: [PATCH 130/154] fix: extdns crashes when virtual service points to nonexistent gateway Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com> updating test Update source/istio_virtualservice_test.go Co-authored-by: John Gardiner Myers Update source/istio_virtualservice_test.go Co-authored-by: John Gardiner Myers --- go.mod | 1 - go.sum | 36 +------- source/istio_virtualservice.go | 9 +- source/istio_virtualservice_test.go | 125 +++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index 227ccc6081..f868948d78 100644 --- a/go.mod +++ b/go.mod @@ -113,7 +113,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.13.0 // indirect github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect - github.com/go-stack/stack v1.8.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/go.sum b/go.sum index ae19339555..caeb456f9a 100644 --- a/go.sum +++ b/go.sum @@ -86,7 +86,6 @@ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1 h1:/ZCtF9JC9VyTN2bdwtHnlpCoJOWxZ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.11.1/go.mod h1:vdlVHq8oUD8W8yUr53RSZ9hKkOcboFcgvhS6nMKH+qc= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= -github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= @@ -167,7 +166,6 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l 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/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -192,8 +190,6 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+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/bodgit/tsig v1.2.0 h1:wNfc7yTk2OuWh/s7nEFa9h+SkIfTn7e4xlFtf1Sgvr4= -github.com/bodgit/tsig v1.2.0/go.mod h1:bsN2ntwGE/s3EeoawjAoKUcAfO4Fr0nGKC72vNF/cqM= github.com/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -370,7 +366,6 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= @@ -384,7 +379,6 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 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/errors v0.19.8 h1:doM+tQdZbUm9gydV9yR+iQNmztbjj7I3sW4sIcAwIzc= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= @@ -421,7 +415,6 @@ github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pL 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/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlONADE= github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= @@ -436,13 +429,12 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ 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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= @@ -455,7 +447,6 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr 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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA= @@ -609,8 +600,6 @@ github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1a github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 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/gophercloud/gophercloud v0.25.0 h1:C3Oae7y0fUVQGSsBrb3zliAjdX+riCSEh4lNMejFNI4= -github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gophercloud/gophercloud v1.4.0 h1:RqEu43vaX0lb0LanZr5BylK5ICVxjpFFoc0sxivyuHU= github.com/gophercloud/gophercloud v1.4.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -667,7 +656,6 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX 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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -704,19 +692,14 @@ github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFK github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE/Tq8= github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/jinzhu/copier v0.3.2/go.mod h1:24xnZezI2Yqac9J61UC6/dG/k76ttpq0DdJI3QmUvro= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -782,7 +765,6 @@ github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= @@ -853,7 +835,6 @@ github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08 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/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c= @@ -944,7 +925,7 @@ github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4 github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= 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= @@ -1236,7 +1217,6 @@ go.etcd.io/etcd/client/v3 v3.5.8/go.mod h1:idZYIPVkttBJBiRigkB5EM0MmEyx8jcl18zCV 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.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= @@ -1291,20 +1271,16 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh 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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1341,7 +1317,6 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -1405,8 +1380,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1530,8 +1503,6 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1545,8 +1516,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1629,7 +1598,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= diff --git a/source/istio_virtualservice.go b/source/istio_virtualservice.go index 934490a803..2e8ecf0edc 100644 --- a/source/istio_virtualservice.go +++ b/source/istio_virtualservice.go @@ -23,12 +23,12 @@ import ( "strings" "text/template" - networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" - log "github.com/sirupsen/logrus" + networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" istioclient "istio.io/client-go/pkg/clientset/versioned" istioinformers "istio.io/client-go/pkg/informers/externalversions" networkingv1alpha3informer "istio.io/client-go/pkg/informers/externalversions/networking/v1alpha3" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" kubeinformers "k8s.io/client-go/informers" @@ -203,7 +203,10 @@ func (sc *virtualServiceSource) getGateway(ctx context.Context, gatewayStr strin } gateway, err := sc.istioClient.NetworkingV1alpha3().Gateways(namespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { + if errors.IsNotFound(err) { + log.Warnf("VirtualService (%s/%s) references non-existent gateway: %s ", virtualService.Namespace, virtualService.Name, gatewayStr) + return nil, nil + } else if err != nil { log.Errorf("Failed retrieving gateway %s referenced by VirtualService %s/%s: %v", gatewayStr, virtualService.Namespace, virtualService.Name, err) return nil, err } diff --git a/source/istio_virtualservice_test.go b/source/istio_virtualservice_test.go index a510094e75..e65c1bad7b 100644 --- a/source/istio_virtualservice_test.go +++ b/source/istio_virtualservice_test.go @@ -18,19 +18,23 @@ package source import ( "context" + "fmt" "testing" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "istio.io/api/meta/v1alpha1" istionetworking "istio.io/api/networking/v1alpha3" networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" istiofake "istio.io/client-go/pkg/clientset/versioned/fake" + fakenetworking3 "istio.io/client-go/pkg/clientset/versioned/typed/networking/v1alpha3/fake" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" + k8sclienttesting "k8s.io/client-go/testing" "sigs.k8s.io/external-dns/endpoint" ) @@ -1579,6 +1583,8 @@ func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, g for _, gw := range gwList { gwObj := gw.Config() + // use create instead of add + // https://github.com/kubernetes/client-go/blob/92512ee2b8cf6696e9909245624175b7f0c971d9/testing/fixture.go#LL336C3-L336C52 _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), &gwObj, metav1.CreateOptions{}) if err != nil { return nil, err @@ -1634,3 +1640,118 @@ func (c fakeVirtualServiceConfig) Config() *networkingv1alpha3.VirtualService { Spec: vs, } } + +func TestVirtualServiceSourceGetGateway(t *testing.T) { + type fields struct { + virtualServiceSource *virtualServiceSource + } + type args struct { + ctx context.Context + gatewayStr string + virtualService *networkingv1alpha3.VirtualService + } + tests := []struct { + name string + fields fields + args args + want *networkingv1alpha3.Gateway + expectedErrStr string + }{ + {name: "EmptyGateway", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { vs, _ := newTestVirtualServiceSource(nil, nil); return vs }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: "", + virtualService: nil, + }, want: nil, expectedErrStr: ""}, + {name: "MeshGateway", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { vs, _ := newTestVirtualServiceSource(nil, nil); return vs }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: IstioMeshGateway, + virtualService: nil, + }, want: nil, expectedErrStr: ""}, + {name: "MissingGateway", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { vs, _ := newTestVirtualServiceSource(nil, nil); return vs }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: "doesnt/exist", + virtualService: &networkingv1alpha3.VirtualService{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{Name: "exist", Namespace: "doesnt"}, + Spec: istionetworking.VirtualService{}, + Status: v1alpha1.IstioStatus{}, + }, + }, want: nil, expectedErrStr: ""}, + {name: "InvalidGatewayStr", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { vs, _ := newTestVirtualServiceSource(nil, nil); return vs }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: "1/2/3/", + virtualService: &networkingv1alpha3.VirtualService{}, + }, want: nil, expectedErrStr: "invalid gateway name (name or namespace/name) found '1/2/3/'"}, + {name: "ExistingGateway", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { + vs, _ := newTestVirtualServiceSource(nil, []fakeGatewayConfig{{ + namespace: "bar", + name: "foo", + }}) + return vs + }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: "bar/foo", + virtualService: &networkingv1alpha3.VirtualService{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, + Spec: istionetworking.VirtualService{}, + Status: v1alpha1.IstioStatus{}, + }, + }, want: &networkingv1alpha3.Gateway{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, + Spec: istionetworking.Gateway{}, + Status: v1alpha1.IstioStatus{}, + }, expectedErrStr: ""}, + {name: "ErrorGettingGateway", fields: fields{ + virtualServiceSource: func() *virtualServiceSource { + istioFake := istiofake.NewSimpleClientset() + istioFake.NetworkingV1alpha3().(*fakenetworking3.FakeNetworkingV1alpha3).PrependReactor("get", "gateways", func(action k8sclienttesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &networkingv1alpha3.Gateway{}, fmt.Errorf("error getting gateway") + }) + vs, _ := NewIstioVirtualServiceSource( + context.TODO(), + fake.NewSimpleClientset(), + istioFake, + "", + "", + "{{.Name}}", + false, + false, + ) + return vs.(*virtualServiceSource) + }(), + }, args: args{ + ctx: context.TODO(), + gatewayStr: "foo/bar", + virtualService: &networkingv1alpha3.VirtualService{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{Name: "gateway", Namespace: "error"}, + Spec: istionetworking.VirtualService{}, + Status: v1alpha1.IstioStatus{}, + }, + }, want: nil, expectedErrStr: "error getting gateway"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.fields.virtualServiceSource.getGateway(tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService) + if tt.expectedErrStr != "" { + assert.EqualError(t, err, tt.expectedErrStr, fmt.Sprintf("getGateway(%v, %v, %v)", tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService)) + return + } else { + require.NoError(t, err) + } + assert.Equalf(t, tt.want, got, "getGateway(%v, %v, %v)", tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService) + }) + } +} From 65e480df0e180a04c46cb44e6ffc703dbc7647b0 Mon Sep 17 00:00:00 2001 From: Matias Charriere Date: Sun, 18 Jun 2023 13:58:16 +0200 Subject: [PATCH 131/154] remove hardcoded check in registry/txt Signed-off-by: Matias Charriere --- registry/txt.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/registry/txt.go b/registry/txt.go index f7d79a6869..e9411185b8 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -286,9 +286,6 @@ func (im *TXTRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) // PropertyValuesEqual compares two attribute values for equality func (im *TXTRegistry) PropertyValuesEqual(name string, previous string, current string) bool { - if name == "txt/force-update" { - return false - } return im.provider.PropertyValuesEqual(name, previous, current) } From 4417ad48947f6f77b341cc00b340e93857465282 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 28 May 2023 10:42:30 -0700 Subject: [PATCH 132/154] Move EndpointKey to endpoints package --- endpoint/endpoint.go | 6 ++++++ source/node.go | 10 +++++----- source/pod.go | 12 ++++++------ source/service.go | 20 ++++++++++---------- source/source.go | 6 ------ 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index e1ed83c5b4..c49f2b7b00 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -162,6 +162,12 @@ type ProviderSpecificProperty struct { // ProviderSpecific holds configuration which is specific to individual DNS providers type ProviderSpecific []ProviderSpecificProperty +// EndpointKey is the type of a map key for separating endpoints or targets. +type EndpointKey struct { + DNSName string + RecordType string +} + // Endpoint is a high-level way of a connection between a service and an IP type Endpoint struct { // The hostname of the DNS record diff --git a/source/node.go b/source/node.go index 63af289f8d..223ec2982d 100644 --- a/source/node.go +++ b/source/node.go @@ -88,7 +88,7 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro return nil, err } - endpoints := map[endpointKey]*endpoint.Endpoint{} + endpoints := map[endpoint.EndpointKey]*endpoint.Endpoint{} // create endpoints for all nodes for _, node := range nodes { @@ -136,13 +136,13 @@ func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, erro ep.Labels = endpoint.NewLabels() for _, addr := range addrs { log.Debugf("adding endpoint %s target %s", ep, addr) - key := endpointKey{ - dnsName: ep.DNSName, - recordType: suitableType(addr), + key := endpoint.EndpointKey{ + DNSName: ep.DNSName, + RecordType: suitableType(addr), } if _, ok := endpoints[key]; !ok { epCopy := *ep - epCopy.RecordType = key.recordType + epCopy.RecordType = key.RecordType endpoints[key] = &epCopy } endpoints[key].Targets = append(endpoints[key].Targets, addr) diff --git a/source/pod.go b/source/pod.go index e399a8906a..2441d28908 100644 --- a/source/pod.go +++ b/source/pod.go @@ -82,7 +82,7 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error return nil, err } - endpointMap := make(map[endpointKey][]string) + endpointMap := make(map[endpoint.EndpointKey][]string) for _, pod := range pods { if !pod.Spec.HostNetwork { log.Debugf("skipping pod %s. hostNetwork=false", pod.Name) @@ -135,15 +135,15 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error } endpoints := []*endpoint.Endpoint{} for key, targets := range endpointMap { - endpoints = append(endpoints, endpoint.NewEndpoint(key.dnsName, key.recordType, targets...)) + endpoints = append(endpoints, endpoint.NewEndpoint(key.DNSName, key.RecordType, targets...)) } return endpoints, nil } -func addToEndpointMap(endpointMap map[endpointKey][]string, domain string, recordType string, address string) { - key := endpointKey{ - dnsName: domain, - recordType: recordType, +func addToEndpointMap(endpointMap map[endpoint.EndpointKey][]string, domain string, recordType string, address string) { + key := endpoint.EndpointKey{ + DNSName: domain, + RecordType: recordType, } if _, ok := endpointMap[key]; !ok { endpointMap[key] = []string{} diff --git a/source/service.go b/source/service.go index 8454308314..de147758dc 100644 --- a/source/service.go +++ b/source/service.go @@ -271,7 +271,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri endpointsType := getEndpointsTypeFromAnnotations(svc.Annotations) - targetsByHeadlessDomainAndType := make(map[endpointKey]endpoint.Targets) + targetsByHeadlessDomainAndType := make(map[endpoint.EndpointKey]endpoint.Targets) for _, subset := range endpointsObject.Subsets { addresses := subset.Addresses if svc.Spec.PublishNotReadyAddresses || sc.alwaysPublishNotReadyAddresses { @@ -325,9 +325,9 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri } } for _, target := range targets { - key := endpointKey{ - dnsName: headlessDomain, - recordType: suitableType(target), + key := endpoint.EndpointKey{ + DNSName: headlessDomain, + RecordType: suitableType(target), } targetsByHeadlessDomainAndType[key] = append(targetsByHeadlessDomainAndType[key], target) } @@ -335,15 +335,15 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri } } - headlessKeys := []endpointKey{} + headlessKeys := []endpoint.EndpointKey{} for headlessKey := range targetsByHeadlessDomainAndType { headlessKeys = append(headlessKeys, headlessKey) } sort.Slice(headlessKeys, func(i, j int) bool { - if headlessKeys[i].dnsName != headlessKeys[j].dnsName { - return headlessKeys[i].dnsName < headlessKeys[j].dnsName + if headlessKeys[i].DNSName != headlessKeys[j].DNSName { + return headlessKeys[i].DNSName < headlessKeys[j].DNSName } - return headlessKeys[i].recordType < headlessKeys[j].recordType + return headlessKeys[i].RecordType < headlessKeys[j].RecordType }) for _, headlessKey := range headlessKeys { allTargets := targetsByHeadlessDomainAndType[headlessKey] @@ -361,9 +361,9 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri } if ttl.IsConfigured() { - endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessKey.dnsName, headlessKey.recordType, ttl, targets...)) + endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessKey.DNSName, headlessKey.RecordType, ttl, targets...)) } else { - endpoints = append(endpoints, endpoint.NewEndpoint(headlessKey.dnsName, headlessKey.recordType, targets...)) + endpoints = append(endpoints, endpoint.NewEndpoint(headlessKey.DNSName, headlessKey.RecordType, targets...)) } } diff --git a/source/source.go b/source/source.go index 5e3cdcf780..bf64fa1852 100644 --- a/source/source.go +++ b/source/source.go @@ -86,12 +86,6 @@ type Source interface { AddEventHandler(context.Context, func()) } -// endpointKey is the type of a map key for separating endpoints or targets. -type endpointKey struct { - dnsName string - recordType string -} - func getTTLFromAnnotations(annotations map[string]string) (endpoint.TTL, error) { ttlNotConfigured := endpoint.TTL(0) ttlAnnotation, exists := annotations[ttlAnnotationKey] From a9ae5ea43a46cb25de64a4016cf5e95df8918a43 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 28 May 2023 10:50:37 -0700 Subject: [PATCH 133/154] Add SetIdentifier to EndpointKey --- endpoint/endpoint.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index c49f2b7b00..7df3f882f9 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -164,8 +164,9 @@ type ProviderSpecific []ProviderSpecificProperty // EndpointKey is the type of a map key for separating endpoints or targets. type EndpointKey struct { - DNSName string - RecordType string + DNSName string + RecordType string + SetIdentifier string } // Endpoint is a high-level way of a connection between a service and an IP @@ -267,6 +268,15 @@ func (e *Endpoint) DeleteProviderSpecificProperty(key string) { } } +// Key returns the EndpointKey of the Endpoint. +func (e *Endpoint) Key() EndpointKey { + return EndpointKey{ + DNSName: e.DNSName, + RecordType: e.RecordType, + SetIdentifier: e.SetIdentifier, + } +} + 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) } From 794a10dfbe43c51fd0ac7d39bb83b8668595db37 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 28 May 2023 19:57:40 -0700 Subject: [PATCH 134/154] Use common code for creating AWS sessions --- main.go | 23 +++++++++-- pkg/apis/externaldns/types.go | 6 +-- provider/aws/aws.go | 41 +------------------ provider/aws/session.go | 75 +++++++++++++++++++++++++++++++++++ provider/awssd/aws_sd.go | 42 +------------------- 5 files changed, 101 insertions(+), 86 deletions(-) create mode 100644 provider/aws/session.go diff --git a/main.go b/main.go index f8cd7896f8..f2b1c3486d 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,9 @@ import ( "syscall" "time" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/route53" + sd "github.com/aws/aws-sdk-go/service/servicediscovery" "github.com/prometheus/client_golang/prometheus/promhttp" log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/labels" @@ -180,6 +183,20 @@ func main() { zoneTypeFilter := provider.NewZoneTypeFilter(cfg.AWSZoneType) zoneTagFilter := provider.NewZoneTagFilter(cfg.AWSZoneTagFilter) + var awsSession *session.Session + if cfg.Provider == "aws" || cfg.Provider == "aws-sd" { + awsSession, err = aws.NewSession( + aws.AWSSessionConfig{ + AssumeRole: cfg.AWSAssumeRole, + AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID, + APIRetries: cfg.AWSAPIRetries, + }, + ) + if err != nil { + log.Fatal(err) + } + } + var p provider.Provider switch cfg.Provider { case "akamai": @@ -207,13 +224,11 @@ func main() { BatchChangeSize: cfg.AWSBatchChangeSize, BatchChangeInterval: cfg.AWSBatchChangeInterval, EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth, - AssumeRole: cfg.AWSAssumeRole, - AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID, - APIRetries: cfg.AWSAPIRetries, PreferCNAME: cfg.AWSPreferCNAME, DryRun: cfg.DryRun, ZoneCacheDuration: cfg.AWSZoneCacheDuration, }, + route53.New(awsSession), ) case "aws-sd": // Check that only compatible Registry is used with AWS-SD @@ -221,7 +236,7 @@ func main() { log.Infof("Registry \"%s\" cannot be used with AWS Cloud Map. Switching to \"aws-sd\".", cfg.Registry) cfg.Registry = "aws-sd" } - p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.AWSAssumeRoleExternalID, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID) + p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID, sd.New(awsSession)) case "azure-dns", "azure": p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun) case "azure-private-dns": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 82f721a143..d7aa192b91 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -457,12 +457,12 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("alibaba-cloud-zone-type", "When using the Alibaba Cloud provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AlibabaCloudZoneType).EnumVar(&cfg.AlibabaCloudZoneType, "", "public", "private") app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private") app.Flag("aws-zone-tags", "When using the AWS provider, filter for zones with these tags").Default("").StringsVar(&cfg.AWSZoneTagFilter) - app.Flag("aws-assume-role", "When using the AWS provider, assume this IAM role. Useful for hosted zones in another AWS account. Specify the full ARN, e.g. `arn:aws:iam::123455567:role/external-dns` (optional)").Default(defaultConfig.AWSAssumeRole).StringVar(&cfg.AWSAssumeRole) - app.Flag("aws-assume-role-external-id", "When using the AWS provider and assuming a role then specify this external ID` (optional)").Default(defaultConfig.AWSAssumeRoleExternalID).StringVar(&cfg.AWSAssumeRoleExternalID) + app.Flag("aws-assume-role", "When using the AWS API, assume this IAM role. Useful for hosted zones in another AWS account. Specify the full ARN, e.g. `arn:aws:iam::123455567:role/external-dns` (optional)").Default(defaultConfig.AWSAssumeRole).StringVar(&cfg.AWSAssumeRole) + app.Flag("aws-assume-role-external-id", "When using the AWS API and assuming a role then specify this external ID` (optional)").Default(defaultConfig.AWSAssumeRoleExternalID).StringVar(&cfg.AWSAssumeRoleExternalID) app.Flag("aws-batch-change-size", "When using the AWS provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSize)).IntVar(&cfg.AWSBatchChangeSize) app.Flag("aws-batch-change-interval", "When using the AWS provider, set the interval between batch changes.").Default(defaultConfig.AWSBatchChangeInterval.String()).DurationVar(&cfg.AWSBatchChangeInterval) app.Flag("aws-evaluate-target-health", "When using the AWS provider, set whether to evaluate the health of a DNS target (default: enabled, disable with --no-aws-evaluate-target-health)").Default(strconv.FormatBool(defaultConfig.AWSEvaluateTargetHealth)).BoolVar(&cfg.AWSEvaluateTargetHealth) - app.Flag("aws-api-retries", "When using the AWS provider, set the maximum number of retries for API calls before giving up.").Default(strconv.Itoa(defaultConfig.AWSAPIRetries)).IntVar(&cfg.AWSAPIRetries) + app.Flag("aws-api-retries", "When using the AWS API, set the maximum number of retries before giving up.").Default(strconv.Itoa(defaultConfig.AWSAPIRetries)).IntVar(&cfg.AWSAPIRetries) app.Flag("aws-prefer-cname", "When using the AWS provider, prefer using CNAME instead of ALIAS (default: disabled)").BoolVar(&cfg.AWSPreferCNAME) app.Flag("aws-zones-cache-duration", "When using the AWS provider, set the zones list cache TTL (0s to disable).").Default(defaultConfig.AWSZoneCacheDuration.String()).DurationVar(&cfg.AWSZoneCacheDuration) app.Flag("aws-sd-service-cleanup", "When using the AWS CloudMap provider, delete empty Services without endpoints (default: disabled)").BoolVar(&cfg.AWSSDServiceCleanup) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index be1997c7ed..4af0998084 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -25,11 +25,8 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/route53" - "github.com/linki/instrumented_http" "github.com/pkg/errors" log "github.com/sirupsen/logrus" @@ -226,49 +223,15 @@ type AWSConfig struct { BatchChangeSize int BatchChangeInterval time.Duration EvaluateTargetHealth bool - AssumeRole string - AssumeRoleExternalID string - APIRetries int PreferCNAME bool DryRun bool ZoneCacheDuration time.Duration } // NewAWSProvider initializes a new AWS Route53 based Provider. -func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) { - config := aws.NewConfig().WithMaxRetries(awsConfig.APIRetries) - - config.WithHTTPClient( - instrumented_http.NewClient(config.HTTPClient, &instrumented_http.Callbacks{ - PathProcessor: func(path string) string { - parts := strings.Split(path, "/") - return parts[len(parts)-1] - }, - }), - ) - - session, err := session.NewSessionWithOptions(session.Options{ - Config: *config, - SharedConfigState: session.SharedConfigEnable, - }) - if err != nil { - return nil, errors.Wrap(err, "failed to instantiate AWS session") - } - - if awsConfig.AssumeRole != "" { - if awsConfig.AssumeRoleExternalID != "" { - log.Infof("Assuming role: %s with external id %s", awsConfig.AssumeRole, awsConfig.AssumeRoleExternalID) - session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole, func(p *stscreds.AssumeRoleProvider) { - p.ExternalID = &awsConfig.AssumeRoleExternalID - })) - } else { - log.Infof("Assuming role: %s", awsConfig.AssumeRole) - session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole)) - } - } - +func NewAWSProvider(awsConfig AWSConfig, client Route53API) (*AWSProvider, error) { provider := &AWSProvider{ - client: route53.New(session), + client: client, domainFilter: awsConfig.DomainFilter, zoneIDFilter: awsConfig.ZoneIDFilter, zoneTypeFilter: awsConfig.ZoneTypeFilter, diff --git a/provider/aws/session.go b/provider/aws/session.go new file mode 100644 index 0000000000..dac0889837 --- /dev/null +++ b/provider/aws/session.go @@ -0,0 +1,75 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package aws + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/linki/instrumented_http" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "sigs.k8s.io/external-dns/pkg/apis/externaldns" +) + +// AWSSessionConfig contains configuration to create a new AWS provider. +type AWSSessionConfig struct { + AssumeRole string + AssumeRoleExternalID string + APIRetries int +} + +func NewSession(awsConfig AWSSessionConfig) (*session.Session, error) { + config := aws.NewConfig().WithMaxRetries(awsConfig.APIRetries) + + config.WithHTTPClient( + instrumented_http.NewClient(config.HTTPClient, &instrumented_http.Callbacks{ + PathProcessor: func(path string) string { + parts := strings.Split(path, "/") + return parts[len(parts)-1] + }, + }), + ) + + session, err := session.NewSessionWithOptions(session.Options{ + Config: *config, + SharedConfigState: session.SharedConfigEnable, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to instantiate AWS session") + } + + if awsConfig.AssumeRole != "" { + if awsConfig.AssumeRoleExternalID != "" { + logrus.Infof("Assuming role: %s with external id %s", awsConfig.AssumeRole, awsConfig.AssumeRoleExternalID) + session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole, func(p *stscreds.AssumeRoleProvider) { + p.ExternalID = &awsConfig.AssumeRoleExternalID + })) + } else { + logrus.Infof("Assuming role: %s", awsConfig.AssumeRole) + session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole)) + } + } + + session.Handlers.Build.PushBack(request.MakeAddToUserAgentHandler("ExternalDNS", externaldns.Version)) + + return session, nil +} diff --git a/provider/awssd/aws_sd.go b/provider/awssd/aws_sd.go index 97cca81cc1..b161622399 100644 --- a/provider/awssd/aws_sd.go +++ b/provider/awssd/aws_sd.go @@ -25,15 +25,10 @@ import ( "strings" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/aws/session" sd "github.com/aws/aws-sdk-go/service/servicediscovery" - "github.com/linki/instrumented_http" log "github.com/sirupsen/logrus" "sigs.k8s.io/external-dns/endpoint" - "sigs.k8s.io/external-dns/pkg/apis/externaldns" "sigs.k8s.io/external-dns/plan" "sigs.k8s.io/external-dns/provider" ) @@ -86,42 +81,9 @@ type AWSSDProvider struct { } // NewAWSSDProvider initializes a new AWS Cloud Map based Provider. -func NewAWSSDProvider(domainFilter endpoint.DomainFilter, namespaceType string, assumeRole string, assumeRoleExternalID string, dryRun, cleanEmptyService bool, ownerID string) (*AWSSDProvider, error) { - config := aws.NewConfig() - - config = config.WithHTTPClient( - instrumented_http.NewClient(config.HTTPClient, &instrumented_http.Callbacks{ - PathProcessor: func(path string) string { - parts := strings.Split(path, "/") - return parts[len(parts)-1] - }, - }), - ) - - sess, err := session.NewSessionWithOptions(session.Options{ - Config: *config, - SharedConfigState: session.SharedConfigEnable, - }) - if err != nil { - return nil, err - } - - if assumeRole != "" { - if assumeRoleExternalID != "" { - log.Infof("Assuming role %q with external ID %q", assumeRole, assumeRoleExternalID) - sess.Config.WithCredentials(stscreds.NewCredentials(sess, assumeRole, func(p *stscreds.AssumeRoleProvider) { - p.ExternalID = &assumeRoleExternalID - })) - } else { - log.Infof("Assuming role: %s", assumeRole) - sess.Config.WithCredentials(stscreds.NewCredentials(sess, assumeRole)) - } - } - - sess.Handlers.Build.PushBack(request.MakeAddToUserAgentHandler("ExternalDNS", externaldns.Version)) - +func NewAWSSDProvider(domainFilter endpoint.DomainFilter, namespaceType string, dryRun, cleanEmptyService bool, ownerID string, client AWSSDClient) (*AWSSDProvider, error) { provider := &AWSSDProvider{ - client: sd.New(sess), + client: client, dryRun: dryRun, namespaceFilter: domainFilter, namespaceTypeFilter: newSdNamespaceFilter(namespaceType), From b902453493f0e3f939604620644cbae26e0cb19b Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 4 Jun 2023 15:37:15 -0700 Subject: [PATCH 135/154] Simplify implementation of inmemory provider --- provider/inmemory/inmemory.go | 122 +++-------- provider/inmemory/inmemory_test.go | 337 +++++------------------------ registry/txt_test.go | 2 +- 3 files changed, 89 insertions(+), 372 deletions(-) diff --git a/provider/inmemory/inmemory.go b/provider/inmemory/inmemory.go index 0abb1c9558..cee6acc246 100644 --- a/provider/inmemory/inmemory.go +++ b/provider/inmemory/inmemory.go @@ -22,6 +22,7 @@ import ( "strings" log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" @@ -132,11 +133,7 @@ func (im *InMemoryProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, return nil, err } - for _, record := range records { - ep := endpoint.NewEndpoint(record.Name, record.Type, record.Target).WithSetIdentifier(record.SetIdentifier) - ep.Labels = record.Labels - endpoints = append(endpoints, ep) - } + endpoints = append(endpoints, copyEndpoints(records)...) } return endpoints, nil @@ -187,11 +184,11 @@ func (im *InMemoryProvider) ApplyChanges(ctx context.Context, changes *plan.Chan } for zoneID := range perZoneChanges { - change := &inMemoryChange{ - Create: convertToInMemoryRecord(perZoneChanges[zoneID].Create), - UpdateNew: convertToInMemoryRecord(perZoneChanges[zoneID].UpdateNew), - UpdateOld: convertToInMemoryRecord(perZoneChanges[zoneID].UpdateOld), - Delete: convertToInMemoryRecord(perZoneChanges[zoneID].Delete), + change := &plan.Changes{ + Create: perZoneChanges[zoneID].Create, + UpdateNew: perZoneChanges[zoneID].UpdateNew, + UpdateOld: perZoneChanges[zoneID].UpdateOld, + Delete: perZoneChanges[zoneID].Delete, } err := im.client.ApplyChanges(ctx, zoneID, change) if err != nil { @@ -202,16 +199,15 @@ func (im *InMemoryProvider) ApplyChanges(ctx context.Context, changes *plan.Chan return nil } -func convertToInMemoryRecord(endpoints []*endpoint.Endpoint) []*inMemoryRecord { - records := []*inMemoryRecord{} +func copyEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint { + records := make([]*endpoint.Endpoint, 0, len(endpoints)) for _, ep := range endpoints { - records = append(records, &inMemoryRecord{ - Type: ep.RecordType, - Name: ep.DNSName, - Target: ep.Targets[0], - SetIdentifier: ep.SetIdentifier, - Labels: ep.Labels, - }) + newEp := endpoint.NewEndpointWithTTL(ep.DNSName, ep.RecordType, ep.RecordTTL, ep.Targets...).WithSetIdentifier(ep.SetIdentifier) + newEp.Labels = endpoint.NewLabels() + for k, v := range ep.Labels { + newEp.Labels[k] = v + } + records = append(records, newEp) } return records } @@ -244,26 +240,7 @@ func (f *filter) EndpointZoneID(endpoint *endpoint.Endpoint, zones map[string]st return matchZoneID } -// inMemoryRecord - record stored in memory -// Type - type of record -// Name - DNS name assigned to the record -// Target - target of the record -type inMemoryRecord struct { - Type string - SetIdentifier string - Name string - Target string - Labels endpoint.Labels -} - -type zone map[string][]*inMemoryRecord - -type inMemoryChange struct { - Create []*inMemoryRecord - UpdateNew []*inMemoryRecord - UpdateOld []*inMemoryRecord - Delete []*inMemoryRecord -} +type zone map[endpoint.EndpointKey]*endpoint.Endpoint type inMemoryClient struct { zones map[string]zone @@ -273,14 +250,14 @@ func newInMemoryClient() *inMemoryClient { return &inMemoryClient{map[string]zone{}} } -func (c *inMemoryClient) Records(zone string) ([]*inMemoryRecord, error) { +func (c *inMemoryClient) Records(zone string) ([]*endpoint.Endpoint, error) { if _, ok := c.zones[zone]; !ok { return nil, ErrZoneNotFound } - records := []*inMemoryRecord{} + var records []*endpoint.Endpoint for _, rec := range c.zones[zone] { - records = append(records, rec...) + records = append(records, rec) } return records, nil } @@ -297,66 +274,44 @@ func (c *inMemoryClient) CreateZone(zone string) error { if _, ok := c.zones[zone]; ok { return ErrZoneAlreadyExists } - c.zones[zone] = map[string][]*inMemoryRecord{} + c.zones[zone] = map[endpoint.EndpointKey]*endpoint.Endpoint{} return nil } -func (c *inMemoryClient) ApplyChanges(ctx context.Context, zoneID string, changes *inMemoryChange) error { +func (c *inMemoryClient) ApplyChanges(ctx context.Context, zoneID string, changes *plan.Changes) error { if err := c.validateChangeBatch(zoneID, changes); err != nil { return err } for _, newEndpoint := range changes.Create { - if _, ok := c.zones[zoneID][newEndpoint.Name]; !ok { - c.zones[zoneID][newEndpoint.Name] = make([]*inMemoryRecord, 0) - } - c.zones[zoneID][newEndpoint.Name] = append(c.zones[zoneID][newEndpoint.Name], newEndpoint) + c.zones[zoneID][newEndpoint.Key()] = newEndpoint } for _, updateEndpoint := range changes.UpdateNew { - for _, rec := range c.zones[zoneID][updateEndpoint.Name] { - if rec.Type == updateEndpoint.Type { - rec.Target = updateEndpoint.Target - break - } - } + c.zones[zoneID][updateEndpoint.Key()] = updateEndpoint } for _, deleteEndpoint := range changes.Delete { - newSet := make([]*inMemoryRecord, 0) - for _, rec := range c.zones[zoneID][deleteEndpoint.Name] { - if rec.Type != deleteEndpoint.Type { - newSet = append(newSet, rec) - } - } - c.zones[zoneID][deleteEndpoint.Name] = newSet + delete(c.zones[zoneID], deleteEndpoint.Key()) } return nil } -func (c *inMemoryClient) updateMesh(mesh map[string]map[string]map[string]bool, record *inMemoryRecord) error { - if _, exists := mesh[record.Name]; exists { - if _, exists := mesh[record.Name][record.Type]; exists { - if mesh[record.Name][record.Type][record.SetIdentifier] { - return ErrDuplicateRecordFound - } - mesh[record.Name][record.Type][record.SetIdentifier] = true - return nil - } - mesh[record.Name][record.Type] = map[string]bool{record.SetIdentifier: true} - return nil +func (c *inMemoryClient) updateMesh(mesh sets.Set[endpoint.EndpointKey], record *endpoint.Endpoint) error { + if mesh.Has(record.Key()) { + return ErrDuplicateRecordFound } - mesh[record.Name] = map[string]map[string]bool{record.Type: {record.SetIdentifier: true}} + mesh.Insert(record.Key()) return nil } // validateChangeBatch validates that the changes passed to InMemory DNS provider is valid -func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChange) error { +func (c *inMemoryClient) validateChangeBatch(zone string, changes *plan.Changes) error { curZone, ok := c.zones[zone] if !ok { return ErrZoneNotFound } - mesh := map[string]map[string]map[string]bool{} + mesh := sets.New[endpoint.EndpointKey]() for _, newEndpoint := range changes.Create { - if c.findByTypeAndSetIdentifier(newEndpoint.Type, newEndpoint.SetIdentifier, curZone[newEndpoint.Name]) != nil { + if _, exists := curZone[newEndpoint.Key()]; exists { return ErrRecordAlreadyExists } if err := c.updateMesh(mesh, newEndpoint); err != nil { @@ -364,7 +319,7 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang } } for _, updateEndpoint := range changes.UpdateNew { - if c.findByTypeAndSetIdentifier(updateEndpoint.Type, updateEndpoint.SetIdentifier, curZone[updateEndpoint.Name]) == nil { + if _, exists := curZone[updateEndpoint.Key()]; !exists { return ErrRecordNotFound } if err := c.updateMesh(mesh, updateEndpoint); err != nil { @@ -372,12 +327,12 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang } } for _, updateOldEndpoint := range changes.UpdateOld { - if rec := c.findByTypeAndSetIdentifier(updateOldEndpoint.Type, updateOldEndpoint.SetIdentifier, curZone[updateOldEndpoint.Name]); rec == nil || rec.Target != updateOldEndpoint.Target { + if rec, exists := curZone[updateOldEndpoint.Key()]; !exists || rec.Targets[0] != updateOldEndpoint.Targets[0] { return ErrRecordNotFound } } for _, deleteEndpoint := range changes.Delete { - if rec := c.findByTypeAndSetIdentifier(deleteEndpoint.Type, deleteEndpoint.SetIdentifier, curZone[deleteEndpoint.Name]); rec == nil || rec.Target != deleteEndpoint.Target { + if rec, exists := curZone[deleteEndpoint.Key()]; !exists || rec.Targets[0] != deleteEndpoint.Targets[0] { return ErrRecordNotFound } if err := c.updateMesh(mesh, deleteEndpoint); err != nil { @@ -386,12 +341,3 @@ func (c *inMemoryClient) validateChangeBatch(zone string, changes *inMemoryChang } return nil } - -func (c *inMemoryClient) findByTypeAndSetIdentifier(recordType, setIdentifier string, records []*inMemoryRecord) *inMemoryRecord { - for _, record := range records { - if record.Type == recordType && record.SetIdentifier == setIdentifier { - return record - } - } - return nil -} diff --git a/provider/inmemory/inmemory_test.go b/provider/inmemory/inmemory_test.go index 2772afed62..275b534101 100644 --- a/provider/inmemory/inmemory_test.go +++ b/provider/inmemory/inmemory_test.go @@ -22,7 +22,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/internal/testutils" "sigs.k8s.io/external-dns/plan" @@ -32,7 +31,6 @@ import ( var _ provider.Provider = &InMemoryProvider{} func TestInMemoryProvider(t *testing.T) { - t.Run("findByType", testInMemoryFindByType) t.Run("Records", testInMemoryRecords) t.Run("validateChangeBatch", testInMemoryValidateChangeBatch) t.Run("ApplyChanges", testInMemoryApplyChanges) @@ -40,114 +38,6 @@ func TestInMemoryProvider(t *testing.T) { t.Run("CreateZone", testInMemoryCreateZone) } -func testInMemoryFindByType(t *testing.T) { - for _, ti := range []struct { - title string - findType string - findSetIdentifier string - records []*inMemoryRecord - expected *inMemoryRecord - expectedEmpty bool - }{ - { - title: "no records, empty type", - findType: "", - records: nil, - expected: nil, - expectedEmpty: true, - }, - { - title: "no records, non-empty type", - findType: endpoint.RecordTypeA, - records: nil, - expected: nil, - expectedEmpty: true, - }, - { - title: "one record, empty type", - findType: "", - records: []*inMemoryRecord{ - { - Type: endpoint.RecordTypeA, - }, - }, - expected: nil, - expectedEmpty: true, - }, - { - title: "one record, wrong type", - findType: endpoint.RecordTypeCNAME, - records: []*inMemoryRecord{ - { - Type: endpoint.RecordTypeA, - }, - }, - expected: nil, - expectedEmpty: true, - }, - { - title: "one record, right type", - findType: endpoint.RecordTypeA, - records: []*inMemoryRecord{ - { - Type: endpoint.RecordTypeA, - }, - }, - expected: &inMemoryRecord{ - Type: endpoint.RecordTypeA, - }, - }, - { - title: "multiple records, right type", - findType: endpoint.RecordTypeA, - records: []*inMemoryRecord{ - { - Type: endpoint.RecordTypeA, - }, - { - Type: endpoint.RecordTypeTXT, - }, - }, - expected: &inMemoryRecord{ - Type: endpoint.RecordTypeA, - }, - }, - { - title: "multiple records, right type and set identifier", - findType: endpoint.RecordTypeA, - findSetIdentifier: "test-set-1", - records: []*inMemoryRecord{ - { - Type: endpoint.RecordTypeA, - SetIdentifier: "test-set-1", - }, - { - Type: endpoint.RecordTypeA, - SetIdentifier: "test-set-2", - }, - { - Type: endpoint.RecordTypeTXT, - }, - }, - expected: &inMemoryRecord{ - Type: endpoint.RecordTypeA, - SetIdentifier: "test-set-1", - }, - }, - } { - t.Run(ti.title, func(t *testing.T) { - c := newInMemoryClient() - record := c.findByTypeAndSetIdentifier(ti.findType, ti.findSetIdentifier, ti.records) - if ti.expectedEmpty { - assert.Nil(t, record) - } else { - require.NotNil(t, record) - assert.Equal(t, *ti.expected, *record) - } - }) - } -} - func testInMemoryRecords(t *testing.T) { for _, ti := range []struct { title string @@ -175,35 +65,12 @@ func testInMemoryRecords(t *testing.T) { title: "records, zone with records", zone: "org", init: map[string]zone{ - "org": { - "example.org": []*inMemoryRecord{ - { - Name: "example.org", - Target: "8.8.8.8", - Type: endpoint.RecordTypeA, - }, - { - Name: "example.org", - Type: endpoint.RecordTypeTXT, - }, - }, - "foo.org": []*inMemoryRecord{ - { - Name: "foo.org", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, - "com": { - "example.com": []*inMemoryRecord{ - { - Name: "example.com", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, + "org": makeZone( + "example.org", "8.8.8.8", endpoint.RecordTypeA, + "example.org", "", endpoint.RecordTypeTXT, + "foo.org", "4.4.4.4", endpoint.RecordTypeCNAME, + ), + "com": makeZone("example.com", "4.4.4.4", endpoint.RecordTypeCNAME), }, expectError: false, expected: []*endpoint.Endpoint{ @@ -246,41 +113,13 @@ func testInMemoryRecords(t *testing.T) { func testInMemoryValidateChangeBatch(t *testing.T) { init := map[string]zone{ - "org": { - "example.org": []*inMemoryRecord{ - { - Name: "example.org", - Target: "8.8.8.8", - Type: endpoint.RecordTypeA, - }, - { - Name: "example.org", - }, - }, - "foo.org": []*inMemoryRecord{ - { - Name: "foo.org", - Target: "bar.org", - Type: endpoint.RecordTypeCNAME, - }, - }, - "foo.bar.org": []*inMemoryRecord{ - { - Name: "foo.bar.org", - Target: "5.5.5.5", - Type: endpoint.RecordTypeA, - }, - }, - }, - "com": { - "example.com": []*inMemoryRecord{ - { - Name: "example.com", - Target: "another-example.com", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, + "org": makeZone( + "example.org", "8.8.8.8", endpoint.RecordTypeA, + "example.org", "", endpoint.RecordTypeTXT, + "foo.org", "bar.org", endpoint.RecordTypeCNAME, + "foo.bar.org", "5.5.5.5", endpoint.RecordTypeA, + ), + "com": makeZone("example.com", "another-example.com", endpoint.RecordTypeCNAME), } for _, ti := range []struct { title string @@ -561,11 +400,11 @@ func testInMemoryValidateChangeBatch(t *testing.T) { t.Run(ti.title, func(t *testing.T) { c := &inMemoryClient{} c.zones = ti.init - ichanges := &inMemoryChange{ - Create: convertToInMemoryRecord(ti.changes.Create), - UpdateNew: convertToInMemoryRecord(ti.changes.UpdateNew), - UpdateOld: convertToInMemoryRecord(ti.changes.UpdateOld), - Delete: convertToInMemoryRecord(ti.changes.Delete), + ichanges := &plan.Changes{ + Create: ti.changes.Create, + UpdateNew: ti.changes.UpdateNew, + UpdateOld: ti.changes.UpdateOld, + Delete: ti.changes.Delete, } err := c.validateChangeBatch(ti.zone, ichanges) if ti.expectError { @@ -579,42 +418,12 @@ func testInMemoryValidateChangeBatch(t *testing.T) { func getInitData() map[string]zone { return map[string]zone{ - "org": { - "example.org": []*inMemoryRecord{ - { - Name: "example.org", - Target: "8.8.8.8", - Type: endpoint.RecordTypeA, - }, - { - Name: "example.org", - Type: endpoint.RecordTypeTXT, - }, - }, - "foo.org": []*inMemoryRecord{ - { - Name: "foo.org", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - "foo.bar.org": []*inMemoryRecord{ - { - Name: "foo.bar.org", - Target: "5.5.5.5", - Type: endpoint.RecordTypeA, - }, - }, - }, - "com": { - "example.com": []*inMemoryRecord{ - { - Name: "example.com", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, + "org": makeZone("example.org", "8.8.8.8", endpoint.RecordTypeA, + "example.org", "", endpoint.RecordTypeTXT, + "foo.org", "4.4.4.4", endpoint.RecordTypeCNAME, + "foo.bar.org", "5.5.5.5", endpoint.RecordTypeA, + ), + "com": makeZone("example.com", "4.4.4.4", endpoint.RecordTypeCNAME), } } @@ -679,36 +488,11 @@ func testInMemoryApplyChanges(t *testing.T) { }, }, expectedZonesState: map[string]zone{ - "org": { - "example.org": []*inMemoryRecord{ - { - Name: "example.org", - Target: "8.8.8.8", - Type: endpoint.RecordTypeA, - }, - { - Name: "example.org", - Type: endpoint.RecordTypeTXT, - }, - }, - "foo.org": []*inMemoryRecord{ - { - Name: "foo.org", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - "foo.bar.org": []*inMemoryRecord{}, - }, - "com": { - "example.com": []*inMemoryRecord{ - { - Name: "example.com", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, + "org": makeZone("example.org", "8.8.8.8", endpoint.RecordTypeA, + "example.org", "", endpoint.RecordTypeTXT, + "foo.org", "4.4.4.4", endpoint.RecordTypeCNAME, + ), + "com": makeZone("example.com", "4.4.4.4", endpoint.RecordTypeCNAME), }, }, { @@ -720,6 +504,7 @@ func testInMemoryApplyChanges(t *testing.T) { DNSName: "foo.bar.new.org", Targets: endpoint.Targets{"4.8.8.9"}, RecordType: endpoint.RecordTypeA, + Labels: endpoint.NewLabels(), }, }, UpdateNew: []*endpoint.Endpoint{ @@ -727,6 +512,7 @@ func testInMemoryApplyChanges(t *testing.T) { DNSName: "foo.bar.org", Targets: endpoint.Targets{"4.8.8.4"}, RecordType: endpoint.RecordTypeA, + Labels: endpoint.NewLabels(), }, }, UpdateOld: []*endpoint.Endpoint{ @@ -734,6 +520,7 @@ func testInMemoryApplyChanges(t *testing.T) { DNSName: "foo.bar.org", Targets: endpoint.Targets{"5.5.5.5"}, RecordType: endpoint.RecordTypeA, + Labels: endpoint.NewLabels(), }, }, Delete: []*endpoint.Endpoint{ @@ -741,48 +528,18 @@ func testInMemoryApplyChanges(t *testing.T) { DNSName: "example.org", Targets: endpoint.Targets{"8.8.8.8"}, RecordType: endpoint.RecordTypeA, + Labels: endpoint.NewLabels(), }, }, }, expectedZonesState: map[string]zone{ - "org": { - "example.org": []*inMemoryRecord{ - { - Name: "example.org", - Type: endpoint.RecordTypeTXT, - }, - }, - "foo.org": []*inMemoryRecord{ - { - Name: "foo.org", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - "foo.bar.org": []*inMemoryRecord{ - { - Name: "foo.bar.org", - Target: "4.8.8.4", - Type: endpoint.RecordTypeA, - }, - }, - "foo.bar.new.org": []*inMemoryRecord{ - { - Name: "foo.bar.new.org", - Target: "4.8.8.9", - Type: endpoint.RecordTypeA, - }, - }, - }, - "com": { - "example.com": []*inMemoryRecord{ - { - Name: "example.com", - Target: "4.4.4.4", - Type: endpoint.RecordTypeCNAME, - }, - }, - }, + "org": makeZone( + "example.org", "", endpoint.RecordTypeTXT, + "foo.org", "4.4.4.4", endpoint.RecordTypeCNAME, + "foo.bar.org", "4.8.8.4", endpoint.RecordTypeA, + "foo.bar.new.org", "4.8.8.9", endpoint.RecordTypeA, + ), + "com": makeZone("example.com", "4.4.4.4", endpoint.RecordTypeCNAME), }, }, } { @@ -815,3 +572,17 @@ func testInMemoryCreateZone(t *testing.T) { err = im.CreateZone("zone") assert.EqualError(t, err, ErrZoneAlreadyExists.Error()) } + +func makeZone(s ...string) map[endpoint.EndpointKey]*endpoint.Endpoint { + if len(s)%3 != 0 { + panic("makeZone arguments must be multiple of 3") + } + + output := map[endpoint.EndpointKey]*endpoint.Endpoint{} + for i := 0; i < len(s); i += 3 { + ep := endpoint.NewEndpoint(s[i], s[i+2], s[i+1]) + output[ep.Key()] = ep + } + + return output +} diff --git a/registry/txt_test.go b/registry/txt_test.go index 2493fbb117..71e56b5b75 100644 --- a/registry/txt_test.go +++ b/registry/txt_test.go @@ -219,7 +219,7 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) { assert.True(t, testutils.SameEndpoints(records, expectedRecords)) // Ensure prefix is case-insensitive - r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "", []string{}, false, nil) + r, _ = NewTXTRegistry(p, "TxT.", "", "owner", time.Hour, "wc", []string{}, false, nil) records, _ = r.Records(ctx) assert.True(t, testutils.SameEndpointLabels(records, expectedRecords)) From 5aae0af68a46c79afc3636647a196aa921a3ea8b Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sat, 27 May 2023 21:59:09 -0700 Subject: [PATCH 136/154] Add DynamoDB registry implementation --- docs/registry/dynamodb.md | 40 ++ docs/registry/registry.md | 3 +- main.go | 5 +- mkdocs.yml | 1 + pkg/apis/externaldns/types.go | 7 +- pkg/apis/externaldns/types_test.go | 4 + registry/dynamodb.go | 442 +++++++++++++ registry/dynamodb_test.go | 995 +++++++++++++++++++++++++++++ 8 files changed, 1493 insertions(+), 4 deletions(-) create mode 100644 docs/registry/dynamodb.md create mode 100644 registry/dynamodb.go create mode 100644 registry/dynamodb_test.go diff --git a/docs/registry/dynamodb.md b/docs/registry/dynamodb.md new file mode 100644 index 0000000000..92f90de693 --- /dev/null +++ b/docs/registry/dynamodb.md @@ -0,0 +1,40 @@ +# The DynamoDB registry + +The DynamoDB registry stores DNS record metadata in an AWS DynamoDB table. + +## The DynamoDB Table + +By default, the DynamoDB registry stores data in the table named `external-dns`. +A different table may be specified using the `--dynamodb-table` flag. + +The table must have a partition (hash) key named `k` and string type. +The table must not have a sort (range) key. + +## IAM permissions + +The ExternalDNS Role must be granted the following permissions: + +```json + { + "Effect": "Allow", + "Action": [ + "DynamoDB:DescribeTable", + "DynamoDB:PartiQLDelete", + "DynamoDB:PartiQLInsert", + "DynamoDB:PartiQLUpdate", + "DynamoDB:Scan" + ], + "Resource": [ + "arn:aws:dynamodb:*:*:table/external-dns" + ] + } +``` + +The region and account ID may be specified explicitly specified instead of using wildcards. + +## Caching + +The DynamoDB registry can optionally cache DNS records read from the provider. This can mitigate +rate limits imposed by the provider. + +Caching is enabled by specifying a cache duration with the `--txt-cache-interval` flag. diff --git a/docs/registry/registry.md b/docs/registry/registry.md index 6d4466b3ec..59a4313ce8 100644 --- a/docs/registry/registry.md +++ b/docs/registry/registry.md @@ -11,6 +11,7 @@ The registry implementation is specified using the `--registry` flag. ## Supported registries -* [txt](txt.md) (default) - Stores in TXT records in the same provider +* [txt](txt.md) (default) - Stores metadata in TXT records in the same provider. +* [dynamodb](dynamodb.md) - Stores metadata in an AWS DynamoDB table. * noop - Passes metadata directly to the provider. For most providers, this means the metadata is not persisted. * aws-sd - Stores metadata in AWS Service Discovery. Only usable with the `aws-sd` provider. diff --git a/main.go b/main.go index f2b1c3486d..65dbb3e7ef 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,7 @@ import ( "time" "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/route53" sd "github.com/aws/aws-sdk-go/service/servicediscovery" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -184,7 +185,7 @@ func main() { zoneTagFilter := provider.NewZoneTagFilter(cfg.AWSZoneTagFilter) var awsSession *session.Session - if cfg.Provider == "aws" || cfg.Provider == "aws-sd" { + if cfg.Provider == "aws" || cfg.Provider == "aws-sd" || cfg.Registry == "dynamodb" { awsSession, err = aws.NewSession( aws.AWSSessionConfig{ AssumeRole: cfg.AWSAssumeRole, @@ -395,6 +396,8 @@ func main() { var r registry.Registry switch cfg.Registry { + case "dynamodb": + r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(awsSession), cfg.AWSDynamoDBTable, cfg.TXTCacheInterval) case "noop": r, err = registry.NewNoopRegistry(p) case "txt": diff --git a/mkdocs.yml b/mkdocs.yml index f20cf1f907..b9ea79fdf5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,6 +15,7 @@ nav: - Registries: - About: registry/registry.md - TXT: registry/txt.md + - DynamoDB: registry/dynamodb.md - Advanced Topics: - Initial Design: initial-design.md - TTL: ttl.md diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index d7aa192b91..a45d9ad306 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -93,6 +93,7 @@ type Config struct { AWSPreferCNAME bool AWSZoneCacheDuration time.Duration AWSSDServiceCleanup bool + AWSDynamoDBTable string AzureConfigFile string AzureResourceGroup string AzureSubscriptionID string @@ -255,6 +256,7 @@ var defaultConfig = &Config{ AWSPreferCNAME: false, AWSZoneCacheDuration: 0 * time.Second, AWSSDServiceCleanup: false, + AWSDynamoDBTable: "external-dns", AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", AzureSubscriptionID: "", @@ -572,13 +574,14 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("policy", "Modify how DNS records are synchronized between sources and providers (default: sync, options: sync, upsert-only, create-only)").Default(defaultConfig.Policy).EnumVar(&cfg.Policy, "sync", "upsert-only", "create-only") // Flags related to the registry - app.Flag("registry", "The registry implementation to use to keep track of DNS record ownership (default: txt, options: txt, noop, aws-sd)").Default(defaultConfig.Registry).EnumVar(&cfg.Registry, "txt", "noop", "aws-sd") - app.Flag("txt-owner-id", "When using the TXT registry, a name that identifies this instance of ExternalDNS (default: default)").Default(defaultConfig.TXTOwnerID).StringVar(&cfg.TXTOwnerID) + app.Flag("registry", "The registry implementation to use to keep track of DNS record ownership (default: txt, options: txt, noop, dynamodb, aws-sd)").Default(defaultConfig.Registry).EnumVar(&cfg.Registry, "txt", "noop", "dynamodb", "aws-sd") + app.Flag("txt-owner-id", "When using the TXT or DynamoDB registry, a name that identifies this instance of ExternalDNS (default: default)").Default(defaultConfig.TXTOwnerID).StringVar(&cfg.TXTOwnerID) app.Flag("txt-prefix", "When using the TXT registry, a custom string that's prefixed to each ownership DNS record (optional). Could contain record type template like '%{record_type}-prefix-'. Mutual exclusive with txt-suffix!").Default(defaultConfig.TXTPrefix).StringVar(&cfg.TXTPrefix) app.Flag("txt-suffix", "When using the TXT registry, a custom string that's suffixed to the host portion of each ownership DNS record (optional). Could contain record type template like '-%{record_type}-suffix'. Mutual exclusive with txt-prefix!").Default(defaultConfig.TXTSuffix).StringVar(&cfg.TXTSuffix) app.Flag("txt-wildcard-replacement", "When using the TXT registry, a custom string that's used instead of an asterisk for TXT records corresponding to wildcard DNS records (optional)").Default(defaultConfig.TXTWildcardReplacement).StringVar(&cfg.TXTWildcardReplacement) app.Flag("txt-encrypt-enabled", "When using the TXT registry, set if TXT records should be encrypted before stored (default: disabled)").BoolVar(&cfg.TXTEncryptEnabled) app.Flag("txt-encrypt-aes-key", "When using the TXT registry, set TXT record decryption and encryption 32 byte aes key (required when --txt-encrypt=true)").Default(defaultConfig.TXTEncryptAESKey).StringVar(&cfg.TXTEncryptAESKey) + app.Flag("dynamodb-table", "When using the DynamoDB registry, the name of the DynamoDB table (default: \"external-dns\")").Default(defaultConfig.AWSDynamoDBTable).StringVar(&cfg.AWSDynamoDBTable) // Flags related to the main control loop app.Flag("txt-cache-interval", "The interval between cache synchronizations in duration format (default: disabled)").Default(defaultConfig.TXTCacheInterval.String()).DurationVar(&cfg.TXTCacheInterval) diff --git a/pkg/apis/externaldns/types_test.go b/pkg/apis/externaldns/types_test.go index d9c68480c0..c66ba92929 100644 --- a/pkg/apis/externaldns/types_test.go +++ b/pkg/apis/externaldns/types_test.go @@ -65,6 +65,7 @@ var ( AWSPreferCNAME: false, AWSZoneCacheDuration: 0 * time.Second, AWSSDServiceCleanup: false, + AWSDynamoDBTable: "external-dns", AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", AzureSubscriptionID: "", @@ -170,6 +171,7 @@ var ( AWSPreferCNAME: true, AWSZoneCacheDuration: 10 * time.Second, AWSSDServiceCleanup: true, + AWSDynamoDBTable: "custom-table", AzureConfigFile: "azure.json", AzureResourceGroup: "arg", AzureSubscriptionID: "arg", @@ -351,6 +353,7 @@ func TestParseFlags(t *testing.T) { "--txt-owner-id=owner-1", "--txt-prefix=associated-txt-record", "--txt-cache-interval=12h", + "--dynamodb-table=custom-table", "--interval=10m", "--min-event-sync-interval=50s", "--once", @@ -464,6 +467,7 @@ func TestParseFlags(t *testing.T) { "EXTERNAL_DNS_AWS_PREFER_CNAME": "true", "EXTERNAL_DNS_AWS_ZONES_CACHE_DURATION": "10s", "EXTERNAL_DNS_AWS_SD_SERVICE_CLEANUP": "true", + "EXTERNAL_DNS_DYNAMODB_TABLE": "custom-table", "EXTERNAL_DNS_POLICY": "upsert-only", "EXTERNAL_DNS_REGISTRY": "noop", "EXTERNAL_DNS_TXT_OWNER_ID": "owner-1", diff --git a/registry/dynamodb.go b/registry/dynamodb.go new file mode 100644 index 0000000000..3a5b3f70f0 --- /dev/null +++ b/registry/dynamodb.go @@ -0,0 +1,442 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package registry + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/dynamodb" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/sets" + + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" +) + +// DynamoDBAPI is the subset of the AWS Route53 API that we actually use. Add methods as required. Signatures must match exactly. +type DynamoDBAPI interface { + DescribeTableWithContext(ctx aws.Context, input *dynamodb.DescribeTableInput, opts ...request.Option) (*dynamodb.DescribeTableOutput, error) + ScanPagesWithContext(ctx aws.Context, input *dynamodb.ScanInput, fn func(*dynamodb.ScanOutput, bool) bool, opts ...request.Option) error + BatchExecuteStatementWithContext(aws.Context, *dynamodb.BatchExecuteStatementInput, ...request.Option) (*dynamodb.BatchExecuteStatementOutput, error) +} + +// DynamoDBRegistry implements registry interface with ownership implemented via an AWS DynamoDB table. +type DynamoDBRegistry struct { + provider provider.Provider + ownerID string // refers to the owner id of the current instance + + dynamodbAPI DynamoDBAPI + table string + + // cache the dynamodb records owned by us. + labels map[endpoint.EndpointKey]endpoint.Labels + orphanedLabels sets.Set[endpoint.EndpointKey] + + // cache the records in memory and update on an interval instead. + recordsCache []*endpoint.Endpoint + recordsCacheRefreshTime time.Time + cacheInterval time.Duration +} + +// NewDynamoDBRegistry returns a new DynamoDBRegistry object. +func NewDynamoDBRegistry(provider provider.Provider, ownerID string, dynamodbAPI DynamoDBAPI, table string, cacheInterval time.Duration) (*DynamoDBRegistry, error) { + if ownerID == "" { + return nil, errors.New("owner id cannot be empty") + } + if table == "" { + return nil, errors.New("table cannot be empty") + } + + return &DynamoDBRegistry{ + provider: provider, + ownerID: ownerID, + dynamodbAPI: dynamodbAPI, + table: table, + cacheInterval: cacheInterval, + }, nil +} + +func (im *DynamoDBRegistry) GetDomainFilter() endpoint.DomainFilterInterface { + return im.provider.GetDomainFilter() +} + +// Records returns the current records from the registry. +func (im *DynamoDBRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { + // If we have the zones cached AND we have refreshed the cache since the + // last given interval, then just use the cached results. + if im.recordsCache != nil && time.Since(im.recordsCacheRefreshTime) < im.cacheInterval { + log.Debug("Using cached records.") + return im.recordsCache, nil + } + + if im.labels == nil { + if err := im.readLabels(ctx); err != nil { + return nil, err + } + } + + records, err := im.provider.Records(ctx) + if err != nil { + return nil, err + } + + orphanedLabels := sets.KeySet(im.labels) + endpoints := make([]*endpoint.Endpoint, 0, len(records)) + for _, record := range records { + key := record.Key() + if labels := im.labels[key]; labels != nil { + record.Labels = labels + orphanedLabels.Delete(key) + } else { + record.Labels = endpoint.NewLabels() + } + + endpoints = append(endpoints, record) + } + + im.orphanedLabels = orphanedLabels + + // Update the cache. + if im.cacheInterval > 0 { + im.recordsCache = endpoints + im.recordsCacheRefreshTime = time.Now() + } + + return endpoints, nil +} + +// ApplyChanges updates the DNS provider and DynamoDB table with the changes. +func (im *DynamoDBRegistry) ApplyChanges(ctx context.Context, changes *plan.Changes) error { + filteredChanges := &plan.Changes{ + Create: changes.Create, + UpdateNew: filterOwnedRecords(im.ownerID, changes.UpdateNew), + UpdateOld: filterOwnedRecords(im.ownerID, changes.UpdateOld), + Delete: filterOwnedRecords(im.ownerID, changes.Delete), + } + + statements := make([]*dynamodb.BatchStatementRequest, 0, len(filteredChanges.Create)+len(filteredChanges.UpdateNew)) + for _, r := range filteredChanges.Create { + if r.Labels == nil { + r.Labels = make(map[string]string) + } + r.Labels[endpoint.OwnerLabelKey] = im.ownerID + + key := r.Key() + oldLabels := im.labels[key] + if oldLabels == nil { + statements = append(statements, &dynamodb.BatchStatementRequest{ + Statement: aws.String(fmt.Sprintf("INSERT INTO %q VALUE {'k':?, 'o':?, 'l':?}", im.table)), + Parameters: []*dynamodb.AttributeValue{ + toDynamoKey(key), + {S: aws.String(im.ownerID)}, + toDynamoLabels(r.Labels), + }, + ConsistentRead: aws.Bool(true), + }) + } else { + im.orphanedLabels.Delete(key) + statements = im.appendUpdate(statements, key, oldLabels, r.Labels) + } + + im.labels[key] = r.Labels + if im.cacheInterval > 0 { + im.addToCache(r) + } + } + + for _, r := range filteredChanges.Delete { + delete(im.labels, r.Key()) + if im.cacheInterval > 0 { + im.removeFromCache(r) + } + } + + oldLabels := make(map[endpoint.EndpointKey]endpoint.Labels, len(filteredChanges.UpdateOld)) + for _, r := range filteredChanges.UpdateOld { + oldLabels[r.Key()] = r.Labels + + // remove old version of record from cache + if im.cacheInterval > 0 { + im.removeFromCache(r) + } + } + + for _, r := range filteredChanges.UpdateNew { + key := r.Key() + statements = im.appendUpdate(statements, key, oldLabels[key], r.Labels) + + // add new version of record to caches + im.labels[key] = r.Labels + if im.cacheInterval > 0 { + im.addToCache(r) + } + } + + err := im.executeStatements(ctx, statements, func(request *dynamodb.BatchStatementRequest, response *dynamodb.BatchStatementResponse) error { + var context string + if strings.HasPrefix(*request.Statement, "INSERT") { + if aws.StringValue(response.Error.Code) == "DuplicateItem" { + // We lost a race with a different owner or another owner has an orphaned ownership record. + key := fromDynamoKey(request.Parameters[0]) + for i, endpoint := range filteredChanges.Create { + if endpoint.Key() == key { + log.Warnf("Skipping endpoint %v because owner does not match", endpoint) + filteredChanges.Create = append(filteredChanges.Create[:i], filteredChanges.Create[i+1:]...) + // The dynamodb insertion failed; remove from our cache. + im.removeFromCache(endpoint) + delete(im.labels, key) + return nil + } + } + } + context = fmt.Sprintf("inserting dynamodb record %q", aws.StringValue(request.Parameters[0].S)) + } else { + context = fmt.Sprintf("updating dynamodb record %q", aws.StringValue(request.Parameters[1].S)) + } + return fmt.Errorf("%s: %s: %s", context, aws.StringValue(response.Error.Code), aws.StringValue(response.Error.Message)) + }) + if err != nil { + im.recordsCache = nil + im.labels = nil + return err + } + + // When caching is enabled, disable the provider from using the cache. + if im.cacheInterval > 0 { + ctx = context.WithValue(ctx, provider.RecordsContextKey, nil) + } + err = im.provider.ApplyChanges(ctx, filteredChanges) + if err != nil { + im.recordsCache = nil + im.labels = nil + return err + } + + statements = make([]*dynamodb.BatchStatementRequest, 0, len(filteredChanges.Delete)+len(im.orphanedLabels)) + for _, r := range filteredChanges.Delete { + statements = im.appendDelete(statements, r.Key()) + } + for r := range im.orphanedLabels { + statements = im.appendDelete(statements, r) + delete(im.labels, r) + } + im.orphanedLabels = nil + return im.executeStatements(ctx, statements, func(request *dynamodb.BatchStatementRequest, response *dynamodb.BatchStatementResponse) error { + im.labels = nil + return fmt.Errorf("deleting dynamodb record %q: %s: %s", aws.StringValue(request.Parameters[0].S), aws.StringValue(response.Error.Code), aws.StringValue(response.Error.Message)) + }) +} + +// PropertyValuesEqual compares two attribute values for equality. +func (im *DynamoDBRegistry) PropertyValuesEqual(name string, previous string, current string) bool { + return im.provider.PropertyValuesEqual(name, previous, current) +} + +// AdjustEndpoints modifies the endpoints as needed by the specific provider. +func (im *DynamoDBRegistry) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoint.Endpoint { + return im.provider.AdjustEndpoints(endpoints) +} + +/** + DynamoDB registry-specific private methods. +*/ + +func (im *DynamoDBRegistry) readLabels(ctx context.Context) error { + table, err := im.dynamodbAPI.DescribeTableWithContext(ctx, &dynamodb.DescribeTableInput{ + TableName: aws.String(im.table), + }) + if err != nil { + return fmt.Errorf("describing table %q: %w", im.table, err) + } + + foundKey := false + for _, def := range table.Table.AttributeDefinitions { + if aws.StringValue(def.AttributeName) == "k" { + if aws.StringValue(def.AttributeType) != "S" { + return fmt.Errorf("table %q attribute \"k\" must have type \"S\"", im.table) + } + foundKey = true + } + } + if !foundKey { + return fmt.Errorf("table %q must have attribute \"k\" of type \"S\"", im.table) + } + + if aws.StringValue(table.Table.KeySchema[0].AttributeName) != "k" { + return fmt.Errorf("table %q must have hash key \"k\"", im.table) + } + if len(table.Table.KeySchema) > 1 { + return fmt.Errorf("table %q must not have a range key", im.table) + } + + labels := map[endpoint.EndpointKey]endpoint.Labels{} + err = im.dynamodbAPI.ScanPagesWithContext(ctx, &dynamodb.ScanInput{ + TableName: aws.String(im.table), + FilterExpression: aws.String("o = :ownerval"), + ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{ + ":ownerval": {S: aws.String(im.ownerID)}, + }, + ProjectionExpression: aws.String("k,l"), + ConsistentRead: aws.Bool(true), + }, func(output *dynamodb.ScanOutput, last bool) bool { + for _, item := range output.Items { + labels[fromDynamoKey(item["k"])] = fromDynamoLabels(item["l"], im.ownerID) + } + return true + }) + if err != nil { + return fmt.Errorf("querying dynamodb: %w", err) + } + + im.labels = labels + return nil +} + +func fromDynamoKey(key *dynamodb.AttributeValue) endpoint.EndpointKey { + split := strings.SplitN(aws.StringValue(key.S), "#", 3) + return endpoint.EndpointKey{ + DNSName: split[0], + RecordType: split[1], + SetIdentifier: split[2], + } +} + +func toDynamoKey(key endpoint.EndpointKey) *dynamodb.AttributeValue { + return &dynamodb.AttributeValue{ + S: aws.String(fmt.Sprintf("%s#%s#%s", key.DNSName, key.RecordType, key.SetIdentifier)), + } +} + +func fromDynamoLabels(label *dynamodb.AttributeValue, owner string) endpoint.Labels { + labels := endpoint.NewLabels() + for k, v := range label.M { + labels[k] = aws.StringValue(v.S) + } + labels[endpoint.OwnerLabelKey] = owner + return labels +} + +func toDynamoLabels(labels endpoint.Labels) *dynamodb.AttributeValue { + labelMap := make(map[string]*dynamodb.AttributeValue, len(labels)) + for k, v := range labels { + if k == endpoint.OwnerLabelKey { + continue + } + labelMap[k] = &dynamodb.AttributeValue{S: aws.String(v)} + } + return &dynamodb.AttributeValue{M: labelMap} +} + +func (im *DynamoDBRegistry) appendUpdate(statements []*dynamodb.BatchStatementRequest, key endpoint.EndpointKey, old endpoint.Labels, new endpoint.Labels) []*dynamodb.BatchStatementRequest { + if len(old) == len(new) { + equal := true + for k, v := range old { + if newV, exists := new[k]; !exists || v != newV { + equal = false + break + } + } + if equal { + return statements + } + } + + return append(statements, &dynamodb.BatchStatementRequest{ + Statement: aws.String(fmt.Sprintf("UPDATE %q SET \"l\"=? WHERE \"k\"=?", im.table)), + Parameters: []*dynamodb.AttributeValue{ + toDynamoLabels(new), + toDynamoKey(key), + }, + }) +} + +func (im *DynamoDBRegistry) appendDelete(statements []*dynamodb.BatchStatementRequest, key endpoint.EndpointKey) []*dynamodb.BatchStatementRequest { + return append(statements, &dynamodb.BatchStatementRequest{ + Statement: aws.String(fmt.Sprintf("DELETE FROM %q WHERE \"k\"=? AND \"o\"=?", im.table)), + Parameters: []*dynamodb.AttributeValue{ + toDynamoKey(key), + {S: aws.String(im.ownerID)}, + }, + }) +} + +func (im *DynamoDBRegistry) executeStatements(ctx context.Context, statements []*dynamodb.BatchStatementRequest, handleErr func(request *dynamodb.BatchStatementRequest, response *dynamodb.BatchStatementResponse) error) error { + for len(statements) > 0 { + var chunk []*dynamodb.BatchStatementRequest + if len(statements) > 25 { + chunk = chunk[:25] + statements = statements[25:] + } else { + chunk = statements + statements = nil + } + + output, err := im.dynamodbAPI.BatchExecuteStatementWithContext(ctx, &dynamodb.BatchExecuteStatementInput{ + Statements: chunk, + }) + if err != nil { + return err + } + + for i, response := range output.Responses { + request := chunk[i] + if response.Error == nil { + op, _, _ := strings.Cut(*request.Statement, " ") + var key string + if op == "UPDATE" { + key = *request.Parameters[1].S + } else { + key = *request.Parameters[0].S + } + log.Infof("%s dynamodb record %q", op, key) + } else { + if err := handleErr(request, response); err != nil { + return err + } + } + } + } + return nil +} + +func (im *DynamoDBRegistry) addToCache(ep *endpoint.Endpoint) { + if im.recordsCache != nil { + im.recordsCache = append(im.recordsCache, ep) + } +} + +func (im *DynamoDBRegistry) removeFromCache(ep *endpoint.Endpoint) { + if im.recordsCache == nil || ep == nil { + // return early. + return + } + + for i, e := range im.recordsCache { + if e.DNSName == ep.DNSName && e.RecordType == ep.RecordType && e.SetIdentifier == ep.SetIdentifier && e.Targets.Same(ep.Targets) { + // We found a match; delete the endpoint from the cache. + im.recordsCache = append(im.recordsCache[:i], im.recordsCache[i+1:]...) + return + } + } +} diff --git a/registry/dynamodb_test.go b/registry/dynamodb_test.go new file mode 100644 index 0000000000..2f62ea3bb1 --- /dev/null +++ b/registry/dynamodb_test.go @@ -0,0 +1,995 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package registry + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/sets" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/internal/testutils" + "sigs.k8s.io/external-dns/plan" + "sigs.k8s.io/external-dns/provider" + "sigs.k8s.io/external-dns/provider/inmemory" +) + +func TestDynamoDBRegistryNew(t *testing.T) { + api, p := newDynamoDBAPIStub(t, nil) + + _, err := NewDynamoDBRegistry(p, "test-owner", api, "test-table", time.Hour) + require.NoError(t, err) + + _, err = NewDynamoDBRegistry(p, "", api, "test-table", time.Hour) + require.EqualError(t, err, "owner id cannot be empty") + + _, err = NewDynamoDBRegistry(p, "test-owner", api, "", time.Hour) + require.EqualError(t, err, "table cannot be empty") +} + +func TestDynamoDBRegistryRecordsBadTable(t *testing.T) { + for _, tc := range []struct { + name string + setup func(desc *dynamodb.TableDescription) + expected string + }{ + { + name: "missing attribute k", + setup: func(desc *dynamodb.TableDescription) { + desc.AttributeDefinitions[0].AttributeName = aws.String("wrong") + }, + expected: "table \"test-table\" must have attribute \"k\" of type \"S\"", + }, + { + name: "wrong attribute type", + setup: func(desc *dynamodb.TableDescription) { + desc.AttributeDefinitions[0].AttributeType = aws.String("SS") + }, + expected: "table \"test-table\" attribute \"k\" must have type \"S\"", + }, + { + name: "wrong key", + setup: func(desc *dynamodb.TableDescription) { + desc.KeySchema[0].AttributeName = aws.String("wrong") + }, + expected: "table \"test-table\" must have hash key \"k\"", + }, + { + name: "has range key", + setup: func(desc *dynamodb.TableDescription) { + desc.AttributeDefinitions = append(desc.AttributeDefinitions, &dynamodb.AttributeDefinition{ + AttributeName: aws.String("o"), + AttributeType: aws.String("S"), + }) + desc.KeySchema = append(desc.KeySchema, &dynamodb.KeySchemaElement{ + AttributeName: aws.String("o"), + KeyType: aws.String("RANGE"), + }) + }, + expected: "table \"test-table\" must not have a range key", + }, + } { + t.Run(tc.name, func(t *testing.T) { + api, p := newDynamoDBAPIStub(t, nil) + tc.setup(&api.tableDescription) + + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", time.Hour) + + _, err := r.Records(context.Background()) + assert.EqualError(t, err, tc.expected) + }) + } +} + +func TestDynamoDBRegistryRecords(t *testing.T) { + api, p := newDynamoDBAPIStub(t, nil) + + ctx := context.Background() + expectedRecords := []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + } + + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", time.Hour) + records, err := r.Records(ctx) + require.Nil(t, err) + + assert.True(t, testutils.SameEndpoints(records, expectedRecords)) +} + +func TestDynamoDBRegistryApplyChanges(t *testing.T) { + for _, tc := range []struct { + name string + stubConfig DynamoDBStubConfig + changes plan.Changes + expectedError string + expectedRecords []*endpoint.Endpoint + }{ + { + name: "create", + changes: plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "new.test-zone.example.org", + Targets: endpoint.Targets{"new.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + SetIdentifier: "set-new", + Labels: map[string]string{ + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectInsert: map[string]map[string]string{ + "new.test-zone.example.org#CNAME#set-new": {endpoint.ResourceLabelKey: "ingress/default/new-ingress"}, + }, + ExpectDelete: sets.New("quux.test-zone.example.org#A#set-2"), + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + { + DNSName: "new.test-zone.example.org", + Targets: endpoint.Targets{"new.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + SetIdentifier: "set-new", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + { + name: "create orphaned", + changes: plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "quux.test-zone.example.org", + Targets: endpoint.Targets{"5.5.5.5"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.ResourceLabelKey: "ingress/default/quux-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{}, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + { + DNSName: "quux.test-zone.example.org", + Targets: endpoint.Targets{"5.5.5.5"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/quux-ingress", + }, + }, + }, + }, + { + name: "create orphaned change", + changes: plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "quux.test-zone.example.org", + Targets: endpoint.Targets{"5.5.5.5"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectUpdate: map[string]map[string]string{ + "quux.test-zone.example.org#A#set-2": {endpoint.ResourceLabelKey: "ingress/default/new-ingress"}, + }, + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + { + DNSName: "quux.test-zone.example.org", + Targets: endpoint.Targets{"5.5.5.5"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + { + name: "create duplicate", + changes: plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "new.test-zone.example.org", + Targets: endpoint.Targets{"new.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + SetIdentifier: "set-new", + Labels: map[string]string{ + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectInsertError: map[string]string{ + "new.test-zone.example.org#CNAME#set-new": "DuplicateItem", + }, + ExpectDelete: sets.New("quux.test-zone.example.org#A#set-2"), + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + { + name: "create error", + changes: plan.Changes{ + Create: []*endpoint.Endpoint{ + { + DNSName: "new.test-zone.example.org", + Targets: endpoint.Targets{"new.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + SetIdentifier: "set-new", + Labels: map[string]string{ + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectInsertError: map[string]string{ + "new.test-zone.example.org#CNAME#set-new": "TestingError", + }, + }, + expectedError: "inserting dynamodb record \"new.test-zone.example.org#CNAME#set-new\": TestingError: testing error", + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + { + name: "update", + changes: plan.Changes{ + UpdateOld: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + }, + UpdateNew: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"new-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectDelete: sets.New("quux.test-zone.example.org#A#set-2"), + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"new-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + { + name: "update change", + changes: plan.Changes{ + UpdateOld: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + }, + UpdateNew: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"new-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectDelete: sets.New("quux.test-zone.example.org#A#set-2"), + ExpectUpdate: map[string]map[string]string{ + "bar.test-zone.example.org#CNAME#": {endpoint.ResourceLabelKey: "ingress/default/new-ingress"}, + }, + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"new-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + { + name: "update error", + changes: plan.Changes{ + UpdateOld: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + }, + UpdateNew: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"new-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/new-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectUpdateError: map[string]string{ + "bar.test-zone.example.org#CNAME#": "TestingError", + }, + }, + expectedError: "updating dynamodb record \"bar.test-zone.example.org#CNAME#\": TestingError: testing error", + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + { + name: "delete", + changes: plan.Changes{ + Delete: []*endpoint.Endpoint{ + { + DNSName: "bar.test-zone.example.org", + Targets: endpoint.Targets{"my-domain.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + }, + }, + stubConfig: DynamoDBStubConfig{ + ExpectDelete: sets.New("bar.test-zone.example.org#CNAME#", "quux.test-zone.example.org#A#set-2"), + }, + expectedRecords: []*endpoint.Endpoint{ + { + DNSName: "foo.test-zone.example.org", + Targets: endpoint.Targets{"foo.loadbalancer.com"}, + RecordType: endpoint.RecordTypeCNAME, + Labels: map[string]string{ + endpoint.OwnerLabelKey: "", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"1.1.1.1"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-1", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/my-ingress", + }, + }, + { + DNSName: "baz.test-zone.example.org", + Targets: endpoint.Targets{"2.2.2.2"}, + RecordType: endpoint.RecordTypeA, + SetIdentifier: "set-2", + Labels: map[string]string{ + endpoint.OwnerLabelKey: "test-owner", + endpoint.ResourceLabelKey: "ingress/default/other-ingress", + }, + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + api, p := newDynamoDBAPIStub(t, &tc.stubConfig) + ctx := context.Background() + + r, _ := NewDynamoDBRegistry(p, "test-owner", api, "test-table", time.Hour) + _, err := r.Records(ctx) + require.Nil(t, err) + + err = r.ApplyChanges(ctx, &tc.changes) + if tc.expectedError == "" { + assert.Nil(t, err) + } else { + assert.EqualError(t, err, tc.expectedError) + } + + assert.Empty(t, tc.stubConfig.ExpectInsert, "all expected inserts made") + assert.Empty(t, tc.stubConfig.ExpectDelete, "all expected deletions made") + + records, err := r.Records(ctx) + require.Nil(t, err) + assert.True(t, testutils.SameEndpoints(records, tc.expectedRecords)) + + r.recordsCache = nil + records, err = r.Records(ctx) + require.Nil(t, err) + assert.True(t, testutils.SameEndpoints(records, tc.expectedRecords)) + if tc.expectedError == "" { + assert.Empty(t, r.orphanedLabels) + } + }) + } +} + +// DynamoDBAPIStub is a minimal implementation of DynamoDBAPI, used primarily for unit testing. +type DynamoDBStub struct { + t *testing.T + stubConfig *DynamoDBStubConfig + tableDescription dynamodb.TableDescription + changesApplied bool +} + +type DynamoDBStubConfig struct { + ExpectInsert map[string]map[string]string + ExpectInsertError map[string]string + ExpectUpdate map[string]map[string]string + ExpectUpdateError map[string]string + ExpectDelete sets.Set[string] +} + +type wrappedProvider struct { + provider.Provider + stub *DynamoDBStub +} + +func (w *wrappedProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { + assert.False(w.stub.t, w.stub.changesApplied, "ApplyChanges already called") + w.stub.changesApplied = true + return w.Provider.ApplyChanges(ctx, changes) +} + +func newDynamoDBAPIStub(t *testing.T, stubConfig *DynamoDBStubConfig) (*DynamoDBStub, provider.Provider) { + stub := &DynamoDBStub{ + t: t, + stubConfig: stubConfig, + tableDescription: dynamodb.TableDescription{ + AttributeDefinitions: []*dynamodb.AttributeDefinition{ + { + AttributeName: aws.String("k"), + AttributeType: aws.String("S"), + }, + }, + KeySchema: []*dynamodb.KeySchemaElement{ + { + AttributeName: aws.String("k"), + KeyType: aws.String("HASH"), + }, + }, + }, + } + p := inmemory.NewInMemoryProvider() + _ = p.CreateZone(testZone) + _ = p.ApplyChanges(context.Background(), &plan.Changes{ + Create: []*endpoint.Endpoint{ + endpoint.NewEndpoint("foo.test-zone.example.org", endpoint.RecordTypeCNAME, "foo.loadbalancer.com"), + endpoint.NewEndpoint("bar.test-zone.example.org", endpoint.RecordTypeCNAME, "my-domain.com"), + endpoint.NewEndpoint("baz.test-zone.example.org", endpoint.RecordTypeA, "1.1.1.1").WithSetIdentifier("set-1"), + endpoint.NewEndpoint("baz.test-zone.example.org", endpoint.RecordTypeA, "2.2.2.2").WithSetIdentifier("set-2"), + }, + }) + return stub, &wrappedProvider{ + Provider: p, + stub: stub, + } +} + +func (r *DynamoDBStub) DescribeTableWithContext(ctx aws.Context, input *dynamodb.DescribeTableInput, opts ...request.Option) (*dynamodb.DescribeTableOutput, error) { + assert.NotNil(r.t, ctx) + assert.Equal(r.t, "test-table", *input.TableName, "table name") + return &dynamodb.DescribeTableOutput{ + Table: &r.tableDescription, + }, nil +} + +func (r *DynamoDBStub) ScanPagesWithContext(ctx aws.Context, input *dynamodb.ScanInput, fn func(*dynamodb.ScanOutput, bool) bool, opts ...request.Option) error { + assert.NotNil(r.t, ctx) + assert.Equal(r.t, "test-table", *input.TableName, "table name") + assert.Equal(r.t, "o = :ownerval", *input.FilterExpression) + assert.Len(r.t, input.ExpressionAttributeValues, 1) + assert.Equal(r.t, "test-owner", *input.ExpressionAttributeValues[":ownerval"].S) + assert.Equal(r.t, "k,l", *input.ProjectionExpression) + assert.True(r.t, *input.ConsistentRead) + fn(&dynamodb.ScanOutput{ + Items: []map[string]*dynamodb.AttributeValue{ + { + "k": &dynamodb.AttributeValue{S: aws.String("bar.test-zone.example.org#CNAME#")}, + "l": &dynamodb.AttributeValue{M: map[string]*dynamodb.AttributeValue{ + endpoint.ResourceLabelKey: {S: aws.String("ingress/default/my-ingress")}, + }}, + }, + { + "k": &dynamodb.AttributeValue{S: aws.String("baz.test-zone.example.org#A#set-1")}, + "l": &dynamodb.AttributeValue{M: map[string]*dynamodb.AttributeValue{ + endpoint.ResourceLabelKey: {S: aws.String("ingress/default/my-ingress")}, + }}, + }, + { + "k": &dynamodb.AttributeValue{S: aws.String("baz.test-zone.example.org#A#set-2")}, + "l": &dynamodb.AttributeValue{M: map[string]*dynamodb.AttributeValue{ + endpoint.ResourceLabelKey: {S: aws.String("ingress/default/other-ingress")}, + }}, + }, + { + "k": &dynamodb.AttributeValue{S: aws.String("quux.test-zone.example.org#A#set-2")}, + "l": &dynamodb.AttributeValue{M: map[string]*dynamodb.AttributeValue{ + endpoint.ResourceLabelKey: {S: aws.String("ingress/default/quux-ingress")}, + }}, + }, + }, + }, true) + return nil +} + +func (r *DynamoDBStub) BatchExecuteStatementWithContext(context aws.Context, input *dynamodb.BatchExecuteStatementInput, option ...request.Option) (*dynamodb.BatchExecuteStatementOutput, error) { + assert.NotNil(r.t, context) + hasDelete := strings.HasPrefix(strings.ToLower(aws.StringValue(input.Statements[0].Statement)), "delete") + assert.Equal(r.t, hasDelete, r.changesApplied, "delete after provider changes, everything else before") + assert.LessOrEqual(r.t, len(input.Statements), 25) + responses := make([]*dynamodb.BatchStatementResponse, 0, len(input.Statements)) + + for _, statement := range input.Statements { + assert.Equal(r.t, hasDelete, strings.HasPrefix(strings.ToLower(aws.StringValue(statement.Statement)), "delete")) + switch aws.StringValue(statement.Statement) { + case "DELETE FROM \"test-table\" WHERE \"k\"=? AND \"o\"=?": + assert.True(r.t, r.changesApplied, "unexpected delete before provider changes") + + key := aws.StringValue(statement.Parameters[0].S) + assert.True(r.t, r.stubConfig.ExpectDelete.Has(key), "unexpected delete for key %q", key) + r.stubConfig.ExpectDelete.Delete(key) + + assert.Equal(r.t, "test-owner", aws.StringValue(statement.Parameters[1].S)) + + responses = append(responses, &dynamodb.BatchStatementResponse{}) + + case "INSERT INTO \"test-table\" VALUE {'k':?, 'o':?, 'l':?}": + assert.False(r.t, r.changesApplied, "unexpected insert after provider changes") + + key := aws.StringValue(statement.Parameters[0].S) + if code, exists := r.stubConfig.ExpectInsertError[key]; exists { + delete(r.stubConfig.ExpectInsertError, key) + responses = append(responses, &dynamodb.BatchStatementResponse{ + Error: &dynamodb.BatchStatementError{ + Code: aws.String(code), + Message: aws.String("testing error"), + }, + }) + break + } + + expectedLabels, found := r.stubConfig.ExpectInsert[key] + assert.True(r.t, found, "unexpected insert for key %q", key) + delete(r.stubConfig.ExpectInsert, key) + + assert.Equal(r.t, "test-owner", aws.StringValue(statement.Parameters[1].S)) + + for label, attribute := range statement.Parameters[2].M { + value := aws.StringValue(attribute.S) + expectedValue, found := expectedLabels[label] + assert.True(r.t, found, "insert for key %q has unexpected label %q", key, label) + delete(expectedLabels, label) + assert.Equal(r.t, expectedValue, value, "insert for key %q label %q value", key, label) + } + + for label := range expectedLabels { + r.t.Errorf("insert for key %q did not get expected label %q", key, label) + } + + responses = append(responses, &dynamodb.BatchStatementResponse{}) + + case "UPDATE \"test-table\" SET \"l\"=? WHERE \"k\"=?": + assert.False(r.t, r.changesApplied, "unexpected update after provider changes") + + key := aws.StringValue(statement.Parameters[1].S) + if code, exists := r.stubConfig.ExpectUpdateError[key]; exists { + delete(r.stubConfig.ExpectInsertError, key) + responses = append(responses, &dynamodb.BatchStatementResponse{ + Error: &dynamodb.BatchStatementError{ + Code: aws.String(code), + Message: aws.String("testing error"), + }, + }) + break + } + + expectedLabels, found := r.stubConfig.ExpectUpdate[key] + assert.True(r.t, found, "unexpected update for key %q", key) + delete(r.stubConfig.ExpectUpdate, key) + + for label, attribute := range statement.Parameters[0].M { + value := aws.StringValue(attribute.S) + expectedValue, found := expectedLabels[label] + assert.True(r.t, found, "update for key %q has unexpected label %q", key, label) + delete(expectedLabels, label) + assert.Equal(r.t, expectedValue, value, "update for key %q label %q value", key, label) + } + + for label := range expectedLabels { + r.t.Errorf("update for key %q did not get expected label %q", key, label) + } + + responses = append(responses, &dynamodb.BatchStatementResponse{}) + + default: + r.t.Errorf("unexpected statement: %s", aws.StringValue(statement.Statement)) + } + } + + return &dynamodb.BatchExecuteStatementOutput{ + Responses: responses, + }, nil +} From 1a4c7b5f3cc307ced6e3f22d3a386d38332ca0ce Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Mon, 12 Jun 2023 19:29:34 -0700 Subject: [PATCH 137/154] Support DynamoDB tables in other regions --- docs/registry/dynamodb.md | 1 + main.go | 7 ++++++- pkg/apis/externaldns/types.go | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/registry/dynamodb.md b/docs/registry/dynamodb.md index 92f90de693..9e5f8331fd 100644 --- a/docs/registry/dynamodb.md +++ b/docs/registry/dynamodb.md @@ -6,6 +6,7 @@ The DynamoDB registry stores DNS record metadata in an AWS DynamoDB table. By default, the DynamoDB registry stores data in the table named `external-dns`. A different table may be specified using the `--dynamodb-table` flag. +A different region may be specified using the `--dynamodb-region` flag. The table must have a partition (hash) key named `k` and string type. The table must not have a sort (range) key. diff --git a/main.go b/main.go index 65dbb3e7ef..d83a4e25d6 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,7 @@ import ( "syscall" "time" + awsSDK "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/route53" @@ -397,7 +398,11 @@ func main() { var r registry.Registry switch cfg.Registry { case "dynamodb": - r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(awsSession), cfg.AWSDynamoDBTable, cfg.TXTCacheInterval) + config := awsSDK.NewConfig() + if cfg.AWSDynamoDBRegion != "" { + config = config.WithRegion(cfg.AWSDynamoDBRegion) + } + r, err = registry.NewDynamoDBRegistry(p, cfg.TXTOwnerID, dynamodb.New(awsSession, config), cfg.AWSDynamoDBTable, cfg.TXTCacheInterval) case "noop": r, err = registry.NewNoopRegistry(p) case "txt": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index a45d9ad306..0b022ef6e5 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -93,6 +93,7 @@ type Config struct { AWSPreferCNAME bool AWSZoneCacheDuration time.Duration AWSSDServiceCleanup bool + AWSDynamoDBRegion string AWSDynamoDBTable string AzureConfigFile string AzureResourceGroup string @@ -256,6 +257,7 @@ var defaultConfig = &Config{ AWSPreferCNAME: false, AWSZoneCacheDuration: 0 * time.Second, AWSSDServiceCleanup: false, + AWSDynamoDBRegion: "", AWSDynamoDBTable: "external-dns", AzureConfigFile: "/etc/kubernetes/azure.json", AzureResourceGroup: "", @@ -581,6 +583,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("txt-wildcard-replacement", "When using the TXT registry, a custom string that's used instead of an asterisk for TXT records corresponding to wildcard DNS records (optional)").Default(defaultConfig.TXTWildcardReplacement).StringVar(&cfg.TXTWildcardReplacement) app.Flag("txt-encrypt-enabled", "When using the TXT registry, set if TXT records should be encrypted before stored (default: disabled)").BoolVar(&cfg.TXTEncryptEnabled) app.Flag("txt-encrypt-aes-key", "When using the TXT registry, set TXT record decryption and encryption 32 byte aes key (required when --txt-encrypt=true)").Default(defaultConfig.TXTEncryptAESKey).StringVar(&cfg.TXTEncryptAESKey) + app.Flag("dynamodb-region", "When using the DynamoDB registry, the AWS region of the DynamoDB table (optional)").Default(cfg.AWSDynamoDBRegion).StringVar(&cfg.AWSDynamoDBRegion) app.Flag("dynamodb-table", "When using the DynamoDB registry, the name of the DynamoDB table (default: \"external-dns\")").Default(defaultConfig.AWSDynamoDBTable).StringVar(&cfg.AWSDynamoDBTable) // Flags related to the main control loop From bb4e7478b70580f2a26d89df0da19caf49e08fdc Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 15 Jun 2023 16:22:41 -0700 Subject: [PATCH 138/154] Address review comments --- provider/aws/session.go | 4 ++-- registry/dynamodb.go | 7 +------ registry/txt.go | 5 ----- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/provider/aws/session.go b/provider/aws/session.go index dac0889837..822ab4aff2 100644 --- a/provider/aws/session.go +++ b/provider/aws/session.go @@ -17,6 +17,7 @@ limitations under the License. package aws import ( + "fmt" "strings" "github.com/aws/aws-sdk-go/aws" @@ -24,7 +25,6 @@ import ( "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" "github.com/linki/instrumented_http" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "sigs.k8s.io/external-dns/pkg/apis/externaldns" @@ -54,7 +54,7 @@ func NewSession(awsConfig AWSSessionConfig) (*session.Session, error) { SharedConfigState: session.SharedConfigEnable, }) if err != nil { - return nil, errors.Wrap(err, "failed to instantiate AWS session") + return nil, fmt.Errorf("instantiating AWS session: %w", err) } if awsConfig.AssumeRole != "" { diff --git a/registry/dynamodb.go b/registry/dynamodb.go index 3a5b3f70f0..6507af6507 100644 --- a/registry/dynamodb.go +++ b/registry/dynamodb.go @@ -201,7 +201,7 @@ func (im *DynamoDBRegistry) ApplyChanges(ctx context.Context, changes *plan.Chan key := fromDynamoKey(request.Parameters[0]) for i, endpoint := range filteredChanges.Create { if endpoint.Key() == key { - log.Warnf("Skipping endpoint %v because owner does not match", endpoint) + log.Infof("Skipping endpoint %v because owner does not match", endpoint) filteredChanges.Create = append(filteredChanges.Create[:i], filteredChanges.Create[i+1:]...) // The dynamodb insertion failed; remove from our cache. im.removeFromCache(endpoint) @@ -258,10 +258,6 @@ func (im *DynamoDBRegistry) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*e return im.provider.AdjustEndpoints(endpoints) } -/** - DynamoDB registry-specific private methods. -*/ - func (im *DynamoDBRegistry) readLabels(ctx context.Context) error { table, err := im.dynamodbAPI.DescribeTableWithContext(ctx, &dynamodb.DescribeTableInput{ TableName: aws.String(im.table), @@ -428,7 +424,6 @@ func (im *DynamoDBRegistry) addToCache(ep *endpoint.Endpoint) { func (im *DynamoDBRegistry) removeFromCache(ep *endpoint.Endpoint) { if im.recordsCache == nil || ep == nil { - // return early. return } diff --git a/registry/txt.go b/registry/txt.go index e9411185b8..3300b5ef1b 100644 --- a/registry/txt.go +++ b/registry/txt.go @@ -294,10 +294,6 @@ func (im *TXTRegistry) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoi return im.provider.AdjustEndpoints(endpoints) } -/** - TXT registry specific private methods -*/ - /** nameMapper is the interface for mapping between the endpoint for the source and the endpoint for the TXT record. @@ -452,7 +448,6 @@ func (im *TXTRegistry) addToCache(ep *endpoint.Endpoint) { func (im *TXTRegistry) removeFromCache(ep *endpoint.Endpoint) { if im.recordsCache == nil || ep == nil { - // return early. return } From 4da80b2ffb7cbced4708b8a13789c4caabbe39bb Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Mon, 19 Jun 2023 10:06:05 +0200 Subject: [PATCH 139/154] partial fix on istio --- source/istio_gateway_test.go | 4 ++-- source/istio_virtualservice_test.go | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/istio_gateway_test.go b/source/istio_gateway_test.go index ebbabd0bbd..7ca79623ca 100644 --- a/source/istio_gateway_test.go +++ b/source/istio_gateway_test.go @@ -1302,7 +1302,7 @@ type fakeGatewayConfig struct { } func (c fakeGatewayConfig) Config() *networkingv1alpha3.Gateway { - gw := networkingv1alpha3.Gateway{ + gw := &networkingv1alpha3.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: c.name, Namespace: c.namespace, @@ -1323,5 +1323,5 @@ func (c fakeGatewayConfig) Config() *networkingv1alpha3.Gateway { gw.Spec.Servers = servers - return &gw + return gw } diff --git a/source/istio_virtualservice_test.go b/source/istio_virtualservice_test.go index 72427f8ad8..1f48210644 100644 --- a/source/istio_virtualservice_test.go +++ b/source/istio_virtualservice_test.go @@ -46,7 +46,7 @@ type VirtualServiceSuite struct { suite.Suite source Source lbServices []*v1.Service - gwconfig networkingv1alpha3.Gateway + gwconfig *networkingv1alpha3.Gateway vsconfig *networkingv1alpha3.VirtualService } @@ -75,12 +75,12 @@ func (suite *VirtualServiceSuite) SetupTest() { suite.NoError(err, "should succeed") } - suite.gwconfig = *(fakeGatewayConfig{ + suite.gwconfig = (fakeGatewayConfig{ name: "foo-gateway-with-targets", namespace: "istio-system", dnsnames: [][]string{{"*"}}, }).Config() - _, err = fakeIstioClient.NetworkingV1alpha3().Gateways(suite.gwconfig.Namespace).Create(context.Background(), &suite.gwconfig, metav1.CreateOptions{}) + _, err = fakeIstioClient.NetworkingV1alpha3().Gateways(suite.gwconfig.Namespace).Create(context.Background(), suite.gwconfig, metav1.CreateOptions{}) suite.NoError(err, "should succeed") suite.vsconfig = (fakeVirtualServiceConfig{ @@ -1585,7 +1585,7 @@ func newTestVirtualServiceSource(loadBalancerList []fakeIngressGatewayService, g gwObj := gw.Config() // use create instead of add // https://github.com/kubernetes/client-go/blob/92512ee2b8cf6696e9909245624175b7f0c971d9/testing/fixture.go#LL336C3-L336C52 - _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), &gwObj, metav1.CreateOptions{}) + _, err := fakeIstioClient.NetworkingV1alpha3().Gateways(gw.namespace).Create(context.Background(), gwObj, metav1.CreateOptions{}) if err != nil { return nil, err } @@ -1637,7 +1637,7 @@ func (c fakeVirtualServiceConfig) Config() *networkingv1alpha3.VirtualService { Namespace: c.namespace, Annotations: c.annotations, }, - Spec: vs, + Spec: *vs.DeepCopy(), } } From a798811aa70299d259af7913454fd5fdfc5b9c89 Mon Sep 17 00:00:00 2001 From: Patrik Cyvoct Date: Thu, 4 Aug 2022 10:17:48 +0200 Subject: [PATCH 140/154] minor fixes to the scaleway provider Two small fixes for the Scaleway provider: - defaults to a bigger page size for listing when there is a lot of domains - avoid sending an empty update zone request Signed-off-by: Patrik Cyvoct --- provider/scaleway/scaleway.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/provider/scaleway/scaleway.go b/provider/scaleway/scaleway.go index bd71aed254..0aa7606d45 100644 --- a/provider/scaleway/scaleway.go +++ b/provider/scaleway/scaleway.go @@ -19,6 +19,7 @@ package scaleway import ( "context" "fmt" + "os" "strconv" "strings" @@ -55,9 +56,19 @@ type ScalewayChange struct { // NewScalewayProvider initializes a new Scaleway DNS provider func NewScalewayProvider(ctx context.Context, domainFilter endpoint.DomainFilter, dryRun bool) (*ScalewayProvider, error) { + var err error + defaultPageSize := uint64(1000) + if envPageSize, ok := os.LookupEnv("SCW_DEFAULT_PAGE_SIZE"); ok { + defaultPageSize, err = strconv.ParseUint(envPageSize, 10, 32) + if err != nil { + log.Infof("Ignoring default page size %s, defaulting to 1000", envPageSize) + defaultPageSize = 1000 + } + } scwClient, err := scw.NewClient( scw.WithEnv(), scw.WithUserAgent("ExternalDNS/"+externaldns.Version), + scw.WithDefaultPageSize(uint32(defaultPageSize)), ) if err != nil { return nil, err @@ -256,6 +267,10 @@ func (p *ScalewayProvider) generateApplyRequests(ctx context.Context, changes *p req.Changes = append(req.Changes, &domain.RecordChange{ Add: recordsToAdd[zoneName], }) + // ignore sending empty update requests + if len(req.Changes) == 1 && len(req.Changes[0].Add.Records) == 0 { + continue + } returnedRequests = append(returnedRequests, req) } From 17ca22c309c8ce0274be683c7a94cfd357a6f7b6 Mon Sep 17 00:00:00 2001 From: Michel Loiseleur Date: Mon, 19 Jun 2023 11:17:51 +0200 Subject: [PATCH 141/154] fix test on istio --- source/istio_virtualservice.go | 1 - source/istio_virtualservice_test.go | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/istio_virtualservice.go b/source/istio_virtualservice.go index 2e8ecf0edc..e6e87e6f5a 100644 --- a/source/istio_virtualservice.go +++ b/source/istio_virtualservice.go @@ -214,7 +214,6 @@ func (sc *virtualServiceSource) getGateway(ctx context.Context, gatewayStr strin log.Debugf("Gateway %s referenced by VirtualService %s/%s not found: %v", gatewayStr, virtualService.Namespace, virtualService.Name, err) return nil, nil } - return gateway, nil } diff --git a/source/istio_virtualservice_test.go b/source/istio_virtualservice_test.go index 1f48210644..551be67061 100644 --- a/source/istio_virtualservice_test.go +++ b/source/istio_virtualservice_test.go @@ -1751,7 +1751,13 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) { } else { require.NoError(t, err) } - assert.Equalf(t, tt.want, got, "getGateway(%v, %v, %v)", tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService) + if tt.want != nil && got != nil { + tt.want.Spec.ProtoReflect() + tt.want.Status.ProtoReflect() + assert.Equalf(t, tt.want, got, "getGateway(%v, %v, %v)", tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService) + } else { + assert.Equalf(t, tt.want, got, "getGateway(%v, %v, %v)", tt.args.ctx, tt.args.gatewayStr, tt.args.virtualService) + } }) } } From 5c0136cfb0dee5b729aefa5127998bd21d47ed6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 04:24:13 +0000 Subject: [PATCH 142/154] build(deps): bump the dev-dependencies group with 41 updates Bumps the dev-dependencies group with 41 updates: [github.com/Azure/azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go), [github.com/Azure/go-autorest/autorest](https://github.com/Azure/go-autorest), [github.com/Azure/go-autorest/autorest/adal](https://github.com/Azure/go-autorest), [github.com/F5Networks/k8s-bigip-ctlr/v2](https://github.com/F5Networks/k8s-bigip-ctlr), [github.com/IBM/networking-go-sdk](https://github.com/IBM/networking-go-sdk), [github.com/StackExchange/dnscontrol/v3](https://github.com/StackExchange/dnscontrol), [github.com/alecthomas/kingpin](https://github.com/alecthomas/kingpin), [github.com/aliyun/alibaba-cloud-sdk-go](https://github.com/aliyun/alibaba-cloud-sdk-go), [github.com/ans-group/sdk-go](https://github.com/ans-group/sdk-go), [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go), [github.com/cloudflare/cloudflare-go](https://github.com/cloudflare/cloudflare-go), [github.com/exoscale/egoscale](https://github.com/exoscale/egoscale), [github.com/infobloxopen/infoblox-go-client/v2](https://github.com/infobloxopen/infoblox-go-client), [github.com/linode/linodego](https://github.com/linode/linodego), [github.com/maxatome/go-testdeep](https://github.com/maxatome/go-testdeep), [github.com/miekg/dns](https://github.com/miekg/dns), [github.com/openshift/api](https://github.com/openshift/api), [github.com/openshift/client-go](https://github.com/openshift/client-go), [github.com/oracle/oci-go-sdk/v65](https://github.com/oracle/oci-go-sdk), [github.com/ovh/go-ovh](https://github.com/ovh/go-ovh), [github.com/pluralsh/gqlclient](https://github.com/pluralsh/gqlclient), [github.com/projectcontour/contour](https://github.com/projectcontour/contour), [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang), [github.com/scaleway/scaleway-sdk-go](https://github.com/scaleway/scaleway-sdk-go), [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns](https://github.com/tencentcloud/tencentcloud-sdk-go), [github.com/ultradns/ultradns-sdk-go](https://github.com/ultradns/ultradns-sdk-go), [github.com/vinyldns/go-vinyldns](https://github.com/vinyldns/go-vinyldns), [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd), [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd), [golang.org/x/net](https://github.com/golang/net), [golang.org/x/oauth2](https://github.com/golang/oauth2), [golang.org/x/sync](https://github.com/golang/sync), [google.golang.org/api](https://github.com/googleapis/google-api-go-client), gopkg.in/ns1/ns1-go.v2, [istio.io/client-go](https://github.com/istio/client-go), [k8s.io/api](https://github.com/kubernetes/api), [k8s.io/client-go](https://github.com/kubernetes/client-go) and [sigs.k8s.io/gateway-api](https://github.com/kubernetes-sigs/gateway-api). Updates `github.com/Azure/azure-sdk-for-go` from 66.0.0+incompatible to 68.0.0+incompatible - [Release notes](https://github.com/Azure/azure-sdk-for-go/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/release.md) - [Commits](https://github.com/Azure/azure-sdk-for-go/compare/v66.0.0...v68.0.0) Updates `github.com/Azure/go-autorest/autorest` from 0.11.28 to 0.11.29 - [Release notes](https://github.com/Azure/go-autorest/releases) - [Changelog](https://github.com/Azure/go-autorest/blob/main/CHANGELOG.md) - [Commits](https://github.com/Azure/go-autorest/compare/autorest/v0.11.28...autorest/v0.11.29) Updates `github.com/Azure/go-autorest/autorest/adal` from 0.9.22 to 0.9.23 - [Release notes](https://github.com/Azure/go-autorest/releases) - [Changelog](https://github.com/Azure/go-autorest/blob/main/CHANGELOG.md) - [Commits](https://github.com/Azure/go-autorest/compare/autorest/adal/v0.9.22...autorest/adal/v0.9.23) Updates `github.com/F5Networks/k8s-bigip-ctlr/v2` from 2.11.1 to 2.13.0 - [Release notes](https://github.com/F5Networks/k8s-bigip-ctlr/releases) - [Changelog](https://github.com/F5Networks/k8s-bigip-ctlr/blob/master/docs/RELEASE-NOTES.rst) - [Commits](https://github.com/F5Networks/k8s-bigip-ctlr/compare/v2.11.1...v2.13.0) Updates `github.com/IBM/networking-go-sdk` from 0.36.0 to 0.42.0 - [Release notes](https://github.com/IBM/networking-go-sdk/releases) - [Changelog](https://github.com/IBM/networking-go-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/IBM/networking-go-sdk/compare/v0.36.0...v0.42.0) Updates `github.com/StackExchange/dnscontrol/v3` from 3.27.1 to 3.31.6 - [Release notes](https://github.com/StackExchange/dnscontrol/releases) - [Changelog](https://github.com/StackExchange/dnscontrol/blob/master/documentation/release-engineering.md) - [Commits](https://github.com/StackExchange/dnscontrol/commits) Updates `github.com/alecthomas/kingpin` from 2.2.5+incompatible to 2.2.6+incompatible - [Release notes](https://github.com/alecthomas/kingpin/releases) - [Commits](https://github.com/alecthomas/kingpin/compare/v2.2.5...v2.2.6) Updates `github.com/aliyun/alibaba-cloud-sdk-go` from 1.62.4 to 1.62.380 - [Release notes](https://github.com/aliyun/alibaba-cloud-sdk-go/releases) - [Changelog](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/ChangeLog.txt) - [Commits](https://github.com/aliyun/alibaba-cloud-sdk-go/compare/v1.62.4...v1.62.380) Updates `github.com/ans-group/sdk-go` from 1.10.4 to 1.16.5 - [Release notes](https://github.com/ans-group/sdk-go/releases) - [Commits](https://github.com/ans-group/sdk-go/compare/v1.10.4...v1.16.5) Updates `github.com/aws/aws-sdk-go` from 1.44.136 to 1.44.285 - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.136...v1.44.285) Updates `github.com/cloudflare/cloudflare-go` from 0.58.1 to 0.69.0 - [Release notes](https://github.com/cloudflare/cloudflare-go/releases) - [Changelog](https://github.com/cloudflare/cloudflare-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/cloudflare/cloudflare-go/compare/v0.58.1...v0.69.0) Updates `github.com/exoscale/egoscale` from 0.97.0 to 1.19.0 - [Release notes](https://github.com/exoscale/egoscale/releases) - [Changelog](https://github.com/exoscale/egoscale/blob/master/CHANGELOG.md) - [Commits](https://github.com/exoscale/egoscale/commits) Updates `github.com/infobloxopen/infoblox-go-client/v2` from 2.1.2-0.20220407114022-6f4c71443168 to 2.3.0 - [Release notes](https://github.com/infobloxopen/infoblox-go-client/releases) - [Changelog](https://github.com/infobloxopen/infoblox-go-client/blob/master/CHANGELOG.rst) - [Commits](https://github.com/infobloxopen/infoblox-go-client/commits/v2.3.0) Updates `github.com/linode/linodego` from 1.9.1 to 1.17.0 - [Release notes](https://github.com/linode/linodego/releases) - [Commits](https://github.com/linode/linodego/compare/v1.9.1...v1.17.0) Updates `github.com/maxatome/go-testdeep` from 1.12.0 to 1.13.0 - [Release notes](https://github.com/maxatome/go-testdeep/releases) - [Commits](https://github.com/maxatome/go-testdeep/compare/v1.12.0...v1.13.0) Updates `github.com/miekg/dns` from 1.1.54 to 1.1.55 - [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release) - [Commits](https://github.com/miekg/dns/compare/v1.1.54...v1.1.55) Updates `github.com/openshift/api` from 0.0.0-20210315202829-4b79815405ec to 3.9.0+incompatible - [Commits](https://github.com/openshift/api/commits) Updates `github.com/openshift/client-go` from 0.0.0-20210112165513-ebc401615f47 to 3.9.0+incompatible - [Commits](https://github.com/openshift/client-go/commits/v3.9.0) Updates `github.com/oracle/oci-go-sdk/v65` from 65.35.0 to 65.41.0 - [Release notes](https://github.com/oracle/oci-go-sdk/releases) - [Changelog](https://github.com/oracle/oci-go-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/oracle/oci-go-sdk/compare/v65.35.0...v65.41.0) Updates `github.com/ovh/go-ovh` from 1.1.0 to 1.4.1 - [Release notes](https://github.com/ovh/go-ovh/releases) - [Commits](https://github.com/ovh/go-ovh/compare/v1.1.0...v1.4.1) Updates `github.com/pluralsh/gqlclient` from 1.1.6 to 1.3.17 - [Release notes](https://github.com/pluralsh/gqlclient/releases) - [Changelog](https://github.com/pluralsh/gqlclient/blob/main/.releaserc) - [Commits](https://github.com/pluralsh/gqlclient/compare/v1.1.6...v1.3.17) Updates `github.com/projectcontour/contour` from 1.23.2 to 1.25.0 - [Release notes](https://github.com/projectcontour/contour/releases) - [Changelog](https://github.com/projectcontour/contour/blob/main/RELEASES.md) - [Commits](https://github.com/projectcontour/contour/compare/v1.23.2...v1.25.0) Updates `github.com/prometheus/client_golang` from 1.15.1 to 1.16.0 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0) Updates `github.com/scaleway/scaleway-sdk-go` from 1.0.0-beta.7.0.20210127161313-bd30bebeac4f to 1.0.0-beta.17 - [Release notes](https://github.com/scaleway/scaleway-sdk-go/releases) - [Changelog](https://github.com/scaleway/scaleway-sdk-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/scaleway/scaleway-sdk-go/commits/v1.0.0-beta.17) Updates `github.com/sirupsen/logrus` from 1.9.0 to 1.9.3 - [Release notes](https://github.com/sirupsen/logrus/releases) - [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md) - [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common` from 1.0.599 to 1.0.684 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.599...v1.0.684) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod` from 1.0.344 to 1.0.684 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.344...v1.0.684) Updates `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns` from 1.0.599 to 1.0.684 - [Commits](https://github.com/tencentcloud/tencentcloud-sdk-go/compare/v1.0.599...v1.0.684) Updates `github.com/ultradns/ultradns-sdk-go` from 0.0.0-20200616202852-e62052662f60 to 1.3.7 - [Release notes](https://github.com/ultradns/ultradns-sdk-go/releases) - [Changelog](https://github.com/ultradns/ultradns-sdk-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/ultradns/ultradns-sdk-go/commits/v1.3.7) Updates `github.com/vinyldns/go-vinyldns` from 0.0.0-20200211145900-fe8a3d82e556 to 0.9.16 - [Release notes](https://github.com/vinyldns/go-vinyldns/releases) - [Commits](https://github.com/vinyldns/go-vinyldns/commits/v0.9.16) Updates `go.etcd.io/etcd/api/v3` from 3.5.8 to 3.5.9 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.8...v3.5.9) Updates `go.etcd.io/etcd/client/v3` from 3.5.8 to 3.5.9 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.8...v3.5.9) Updates `golang.org/x/net` from 0.10.0 to 0.11.0 - [Commits](https://github.com/golang/net/compare/v0.10.0...v0.11.0) Updates `golang.org/x/oauth2` from 0.7.0 to 0.9.0 - [Commits](https://github.com/golang/oauth2/compare/v0.7.0...v0.9.0) Updates `golang.org/x/sync` from 0.2.0 to 0.3.0 - [Commits](https://github.com/golang/sync/compare/v0.2.0...v0.3.0) Updates `google.golang.org/api` from 0.120.0 to 0.128.0 - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.120.0...v0.128.0) Updates `gopkg.in/ns1/ns1-go.v2` from 2.7.4 to 2.7.6 Updates `istio.io/client-go` from 0.0.0-20210128182905-ee2edd059e02 to 1.18.0 - [Commits](https://github.com/istio/client-go/commits/v1.18.0) Updates `k8s.io/api` from 0.27.0 to 0.27.3 - [Commits](https://github.com/kubernetes/api/compare/v0.27.0...v0.27.3) Updates `k8s.io/client-go` from 0.27.0 to 0.27.3 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.27.0...v0.27.3) Updates `sigs.k8s.io/gateway-api` from 0.6.2 to 0.7.1 - [Release notes](https://github.com/kubernetes-sigs/gateway-api/releases) - [Changelog](https://github.com/kubernetes-sigs/gateway-api/blob/main/CHANGELOG.md) - [Commits](https://github.com/kubernetes-sigs/gateway-api/compare/v0.6.2...v0.7.1) --- updated-dependencies: - dependency-name: github.com/Azure/azure-sdk-for-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/Azure/go-autorest/autorest dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/Azure/go-autorest/autorest/adal dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/F5Networks/k8s-bigip-ctlr/v2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/IBM/networking-go-sdk dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/StackExchange/dnscontrol/v3 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/alecthomas/kingpin dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/aliyun/alibaba-cloud-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/ans-group/sdk-go dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/cloudflare/cloudflare-go dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/exoscale/egoscale dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/infobloxopen/infoblox-go-client/v2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/linode/linodego dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/maxatome/go-testdeep dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/miekg/dns dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/openshift/api dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/openshift/client-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/oracle/oci-go-sdk/v65 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/ovh/go-ovh dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/pluralsh/gqlclient dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/projectcontour/contour dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: github.com/scaleway/scaleway-sdk-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/sirupsen/logrus dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: github.com/ultradns/ultradns-sdk-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: github.com/vinyldns/go-vinyldns dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: go.etcd.io/etcd/api/v3 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: go.etcd.io/etcd/client/v3 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: golang.org/x/sync dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: gopkg.in/ns1/ns1-go.v2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: istio.io/client-go dependency-type: direct:production update-type: version-update:semver-major - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: sigs.k8s.io/gateway-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index ad8f487b06..df8ec7be7d 100644 --- a/go.mod +++ b/go.mod @@ -15,9 +15,9 @@ require ( github.com/StackExchange/dnscontrol/v3 v3.31.6 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 github.com/alecthomas/kingpin v2.2.6+incompatible - github.com/aliyun/alibaba-cloud-sdk-go v1.62.377 + github.com/aliyun/alibaba-cloud-sdk-go v1.62.380 github.com/ans-group/sdk-go v1.16.5 - github.com/aws/aws-sdk-go v1.44.283 + github.com/aws/aws-sdk-go v1.44.285 github.com/bodgit/tsig v1.2.2 github.com/civo/civogo v0.3.14 github.com/cloudflare/cloudflare-go v0.69.0 @@ -36,11 +36,11 @@ require ( github.com/linki/instrumented_http v0.3.0 github.com/linode/linodego v1.17.0 github.com/maxatome/go-testdeep v1.13.0 - github.com/miekg/dns v1.1.54 + github.com/miekg/dns v1.1.55 github.com/nesv/go-dynect v0.6.0 github.com/nic-at/rc0go v1.1.1 github.com/onsi/ginkgo v1.16.5 - github.com/openshift/api v3.9.0+incompatible + github.com/openshift/api v0.0.0-20230607130528-611114dca681 github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3 github.com/oracle/oci-go-sdk/v65 v65.41.0 github.com/ovh/go-ovh v1.4.1 @@ -51,9 +51,9 @@ require ( github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.684 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.684 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.684 github.com/transip/gotransip/v6 v6.20.0 github.com/ultradns/ultradns-sdk-go v1.3.7 github.com/vinyldns/go-vinyldns v0.9.16 @@ -70,9 +70,9 @@ require ( gopkg.in/yaml.v2 v2.4.0 istio.io/api v0.0.0-20230524015941-fa6c5f7916bf istio.io/client-go v1.18.0 - k8s.io/api v0.27.2 - k8s.io/apimachinery v0.27.2 - k8s.io/client-go v0.27.2 + k8s.io/api v0.27.3 + k8s.io/apimachinery v0.27.3 + k8s.io/client-go v0.27.3 sigs.k8s.io/gateway-api v0.7.1 ) diff --git a/go.sum b/go.sum index 3e55d4233f..ca621a003c 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,8 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAu github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4= github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.377 h1:6czd9jysvWELv3Yiip7dZJhBVKojt+GdWIrddzokEgY= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.377/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.380 h1:ycRtdJGvv88OHxj5Pj9U9zHSo8rSFwGx99ba2N2/VOY= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.380/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -158,8 +158,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W 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.283 h1:ObMaIvdhHJM2sIrbcljd7muHBaFb+Kp/QsX6iflGDg4= -github.com/aws/aws-sdk-go v1.44.283/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.285 h1:rgoWYl+NdmKzRgoi/fZLEtGXOjCkcWIa5jPH02Uahdo= +github.com/aws/aws-sdk-go v1.44.285/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 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -757,8 +757,8 @@ github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08 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/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= @@ -848,8 +848,8 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X 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 v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= -github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +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/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b h1:it0YPE/evO6/m8t8wxis9KFI2F/aleOKsI6d9uz0cEk= @@ -1040,12 +1040,12 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682 h1:k00Y/PASfeb/ekWRK4RByIX/5guZ6o0lc3WNxIPq35o= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.682/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682 h1:AVIySVUzJw1XBoJd5C/g0tyXiTNRaWDrjUc16NMU4Ec= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.682/go.mod h1:Ty5osmJagHfoO/7NQoddIsEmm1kzvnGoie1W9PQaaVo= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682 h1:dIWG/6zUfwo+kcFRID+ta6txig4UTskOfP7Tn2SXF0I= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.682/go.mod h1:KPHBkCraRInvJ4xAkQcnzvqMU1d4VOXsF8gRAs8MEBQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.684 h1:xnx5G6+hwH/tuVDbi4nWTykMXrU5CopIf/uKESAPiO4= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.684/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.684 h1:0W0kMFSMH1wmHDH2u8E7FCMx9KcNpeqz/CKxvEw0+hU= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.684/go.mod h1:coy6xxRqMqBCeCIvJJykUsVh0MdRP9FhL4tW4FhSEq8= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.684 h1:Ed7JypbR/k9DeV6L4xjcX7LUa8vZlA91G6Tp1eDSe3s= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.684/go.mod h1:+okbYzwXLiIIooY7g5VdAqg3kdjhEcb8XS7QJ7qxK1E= github.com/terra-farm/udnssdk v1.3.5 h1:MNR3adfuuEK/l04+jzo8WW/0fnorY+nW515qb3vEr6I= github.com/terra-farm/udnssdk v1.3.5/go.mod h1:8RnM56yZTR7mYyUIvrDgXzdRaEyFIzqdEi7+um26Sv8= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= @@ -1662,16 +1662,16 @@ istio.io/gogo-genproto v0.0.0-20190904133402-ee07f2785480/go.mod h1:uKtbae4K9k2r 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.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= -k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= +k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= +k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= 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/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.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= -k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= +k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= 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= @@ -1680,8 +1680,8 @@ 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.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= -k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= +k8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8= +k8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48= 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= From 2df31d410ba134d1fd65e73587b15c4f0e883986 Mon Sep 17 00:00:00 2001 From: Jameel Al-Aziz <247849+jalaziz@users.noreply.github.com> Date: Fri, 23 Jun 2023 01:48:20 -0700 Subject: [PATCH 143/154] Update aws IAM policy example Update the IAM policy example to include `route53:ListTagsForResource` permissions. This is required for `--aws-zone-tags`. --- docs/tutorials/aws.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index fb96ec3e15..be05cad6e4 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -29,7 +29,8 @@ Hosted Zone IDs. "Effect": "Allow", "Action": [ "route53:ListHostedZones", - "route53:ListResourceRecordSets" + "route53:ListResourceRecordSets", + "route53:ListTagsForResource" ], "Resource": [ "*" From 4ee8bae85c0d6858e4484b4fbd9ffb1390d3fdbc Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 25 Jun 2023 12:25:29 -0700 Subject: [PATCH 144/154] refactor: don't iterate over load balancer if not using result --- source/service.go | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/source/service.go b/source/service.go index de147758dc..6801d984d9 100644 --- a/source/service.go +++ b/source/service.go @@ -562,12 +562,12 @@ func extractServiceExternalName(svc *v1.Service) endpoint.Targets { } func extractLoadBalancerTargets(svc *v1.Service, resolveLoadBalancerHostname bool) endpoint.Targets { - var ( - targets endpoint.Targets - externalIPs endpoint.Targets - ) + if len(svc.Spec.ExternalIPs) > 0 { + return svc.Spec.ExternalIPs + } // Create a corresponding endpoint for each configured external entrypoint. + var targets endpoint.Targets for _, lb := range svc.Status.LoadBalancer.Ingress { if lb.IP != "" { targets = append(targets, lb.IP) @@ -588,16 +588,6 @@ func extractLoadBalancerTargets(svc *v1.Service, resolveLoadBalancerHostname boo } } - if svc.Spec.ExternalIPs != nil { - for _, ext := range svc.Spec.ExternalIPs { - externalIPs = append(externalIPs, ext) - } - } - - if len(externalIPs) > 0 { - return externalIPs - } - return targets } From 039f1a91fb704345a853a130ba2ee5e07d42993f Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 25 Jun 2023 12:39:27 -0700 Subject: [PATCH 145/154] refactor: simplify assignment to Service target list --- source/service.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source/service.go b/source/service.go index 6801d984d9..b19ba48825 100644 --- a/source/service.go +++ b/source/service.go @@ -498,16 +498,15 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro switch svc.Spec.Type { case v1.ServiceTypeLoadBalancer: if useClusterIP { - targets = append(targets, extractServiceIps(svc)...) + targets = extractServiceIps(svc) } else { - targets = append(targets, extractLoadBalancerTargets(svc, sc.resolveLoadBalancerHostname)...) + targets = extractLoadBalancerTargets(svc, sc.resolveLoadBalancerHostname) } case v1.ServiceTypeClusterIP: - if sc.publishInternal { - targets = append(targets, extractServiceIps(svc)...) - } if svc.Spec.ClusterIP == v1.ClusterIPNone { endpoints = append(endpoints, sc.extractHeadlessEndpoints(svc, hostname, ttl)...) + } else if sc.publishInternal { + targets = extractServiceIps(svc) } case v1.ServiceTypeNodePort: // add the nodeTargets and extract an SRV endpoint @@ -518,7 +517,7 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro } endpoints = append(endpoints, sc.extractNodePortEndpoints(svc, hostname, ttl)...) case v1.ServiceTypeExternalName: - targets = append(targets, extractServiceExternalName(svc)...) + targets = extractServiceExternalName(svc) } } From 7c3615434106aaa0c801b3dae711f1f73dec62f2 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Sun, 25 Jun 2023 11:09:37 -0700 Subject: [PATCH 146/154] Document annotations --- docs/annotations/annotations.md | 120 ++++++++++++++++++++++++++++++++ mkdocs.yml | 2 + 2 files changed, 122 insertions(+) create mode 100644 docs/annotations/annotations.md diff --git a/docs/annotations/annotations.md b/docs/annotations/annotations.md new file mode 100644 index 0000000000..79957c1393 --- /dev/null +++ b/docs/annotations/annotations.md @@ -0,0 +1,120 @@ +# Annotations + +ExternalDNS sources support a number of annotations on the Kubernetes resources that they examine. + +The following table documents which sources support which annotations: + +| Source | controller | hostname | internal-hostname | target | ttl | (provider-specific) | +|--------------|------------|----------|-------------------|---------|-----|---------------------| +| Ambassador | | | | | Yes | | +| Connector | | | | | | | +| Contour | Yes | Yes[^1] | | Yes | Yes | Yes | +| CloudFoundry | | | | | | | +| CRD | | | | | | | +| F5 | | | | | Yes | | +| Gateway | Yes | Yes[^1] | | | Yes | Yes | +| Gloo | | | | | Yes | Yes | +| Ingress | Yes | Yes[^1] | | Yes | Yes | Yes | +| Istio | Yes | Yes[^1] | | Yes | Yes | Yes | +| Kong | | Yes | | | Yes | Yes | +| Node | Yes | | | | Yes | | +| OpenShift | Yes | Yes[^1] | | Yes | Yes | Yes | +| Pod | | Yes | Yes | | | | +| Service | Yes | Yes[^1] | Yes[^1][^2] | Yes[^3] | Yes | Yes | +| Skipper | Yes | Yes[^1] | | Yes | Yes | Yes | +| Traefik | | Yes | | Yes | Yes | Yes | + +[^1]: Unless the `--ignore-hostname-annotation` flag is specified. +[^2]: Only behaves differently than `hostname` for `Service`s of type `LoadBalancer`. +[^3]: Also supported on `Pods` referenced from a headless `Service`'s `Endpoints`. + +## external-dns.alpha.kubernetes.io/access + +Specifies which set of node IP addresses to use for a `Service` of type `NodePort`. + +If the value is `public`, use the Nodes' addresses of type `ExternalIP`, plus IPv6 addresses of type `InternalIP`. + +If the value is `private`, use the Nodes' addresses of type `InternalIP`. + +If the annotation is not present and there is at least one address of type `ExternalIP`, +behave as if the value were `public`, otherwise behave as if the value were `private`. + +## external-dns.alpha.kubernetes.io/controller + +If this annotation exists and has a value other than `dns-controller` then the source ignores the resource. + +## external-dns.alpha.kubernetes.io/endpoints-type + +Specifies which set of addresses to use for a headless `Service`. + +If the value is `NodeExternalIP`, use each relevant `Pod`'s `Node`'s address of type `ExternalIP` +plus each IPv6 address of type `InternalIP`. + +Otherwise, if the value is `HostIP` or the `--publish-host-ip` flag is specified, use +each relevant `Pod`'s `Status.HostIP`. + +Otherwise, use the `IP` of each of the `Service`'s `Endpoints`'s `Addresses`. + +## external-dns.alpha.kubernetes.io/hostname + +Specifies the domain for the resource's DNS records. + +## external-dns.alpha.kubernetes.io/ingress-hostname-source + +Specifies where to get the domain for an `Ingress` resource. + +If the value is `defined-hosts-only`, use only the domains from the `Ingress` spec. + +If the value is `annotation-only`, use only the domains from the `Ingress` annotations. + +If the annotation is not present, use the domains from both the spec and annotations. + +## external-dns.alpha.kubernetes.io/internal-hostname + +Specifies the domain for the resource's DNS records that are for use from internal networks. + +For `Services` of type `LoadBalancer`, uses the `Service`'s `ClusterIP`. + +For `Pods`, uses the `Pod`'s `Status.PodIP`. + +## external-dns.alpha.kubernetes.io/target + +Specifies a comma-separated list of values to override the resource's DNS record targets (RDATA). + +Targets that parse as IPv4 addresses are published as A records and +targets that parse as IPv6 addresses are published as AAAA records. All other targets +are published as CNAME records. + +## external-dns.alpha.kubernetes.io/ttl + +Specifies the TTL (time to live) for the resource's DNS records. + +The value may be specified as either a duration or an integer number of seconds. +It must be between 1 and 2,147,483,647 seconds. + +## Provider-specific annotations + +Some providers define their own annotations. Cloud-specific annotations have keys prefixed as follows: + +| Cloud | Annotation prefix | +|------------|------------------------------------------------| +| AWS | `external-dns.alpha.kubernetes.io/aws-` | +| CloudFlare | `external-dns.alpha.kubernetes.io/cloudflare-` | +| IBM Cloud | `external-dns.alpha.kubernetes.io/ibmcloud-` | +| Scaleway | `external-dns.alpha.kubernetes.io/scw-` | + +Additional annotations that are currently implemented only by AWS are: + +### external-dns.alpha.kubernetes.io/alias + +If the value of this annotation is `true`, specifies that CNAME records generated by the +resource should instead be alias records. + +This annotation is only relevant if the `--aws-prefer-cname` flag is specified. + +### external-dns.alpha.kubernetes.io/set-identifier + +Specifies the set identifier for DNS records generated by the resource. + +A set identifier differentiates among multiple DNS record sets that have the same combination of domain and type. +Which record set or sets are returned to queries is then determined by the configured routing policy. diff --git a/mkdocs.yml b/mkdocs.yml index b9ea79fdf5..4714287211 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,6 +12,8 @@ nav: - Code of Conduct: code-of-conduct.md - License: LICENSE.md - Tutorials: tutorials/ + - Annotations: + - About: annotations/annotations.md - Registries: - About: registry/registry.md - TXT: registry/txt.md From 101759608569a01cb11909ac6ee1d52d143f2178 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 04:04:28 +0000 Subject: [PATCH 147/154] build(deps): bump the dev-dependencies group with 1 update Bumps the dev-dependencies group with 1 update: [GrantBirki/json-yaml-validate](https://github.com/grantbirki/json-yaml-validate). - [Release notes](https://github.com/grantbirki/json-yaml-validate/releases) - [Commits](https://github.com/grantbirki/json-yaml-validate/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: GrantBirki/json-yaml-validate dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] --- .github/workflows/json-yaml-validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/json-yaml-validate.yml b/.github/workflows/json-yaml-validate.yml index 1e71e7547d..d551229188 100644 --- a/.github/workflows/json-yaml-validate.yml +++ b/.github/workflows/json-yaml-validate.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - name: json-yaml-validate - uses: GrantBirki/json-yaml-validate@v1.4.0 + uses: GrantBirki/json-yaml-validate@v1.5.0 with: comment: "true" # enable comment mode yaml_exclude_regex: "(charts/external-dns/templates.*|mkdocs.yml)" From 0873103ca4feb8a2d205daa7d5e01680b236e6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20J=2E=20Nu=C3=B1ez=20Madrazo?= Date: Mon, 26 Jun 2023 07:12:41 +0100 Subject: [PATCH 148/154] Update the go.sum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro J. Nuñez Madrazo --- go.sum | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/go.sum b/go.sum index b255df4546..ca621a003c 100644 --- a/go.sum +++ b/go.sum @@ -81,7 +81,6 @@ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.0 h1:oHBU4lCjA3SeuF7Q2uZ/YH169N3f+ github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.0/go.mod h1:GJ5fTJ9GuGe2CzEYd8hk/KinNXDNJ0QYqWluiPdLn/s= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0 h1:m2VQ7wYE8k3ZuV0iIuye5QIK/t6QLZa4BqOx+CteBTo= github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0/go.mod h1:/xwZEX9hm7/YFFEEiFa0Bes2YP5OWmXvgf9D/0o9jic= -github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= github.com/IBM/go-sdk-core/v5 v5.13.4 h1:kJvBNQOwhFRkXCPapjNvKVC7n7n2vd1Nr6uUtDZGcfo= github.com/IBM/go-sdk-core/v5 v5.13.4/go.mod h1:gKRSB+YyKsGlRQW7v5frlLbue5afulSvrRa4O26o4MM= github.com/IBM/networking-go-sdk v0.42.0 h1:tgUwkAdKRnbnovAUxRkHHFajnnjVrhbTXv5YLjRHXAo= @@ -191,8 +190,8 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/civo/civogo v0.3.33 h1:asqRaD5Fp+JyPBXrsGqRbjTSTZ5zKeRhJrJfdV4bPTg= -github.com/civo/civogo v0.3.33/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak= +github.com/civo/civogo v0.3.14 h1:W+o+hFXtEhWyJOmZOm2C5s8OEorSXGP6eyPYOa69NA8= +github.com/civo/civogo v0.3.14/go.mod h1:SbS06e0JPgIF27r1sLC97gjU1xWmONQeHgzF1hfLpak= 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/cloudflare/cloudflare-go v0.69.0 h1:DHRjCQyM0p4qd3e0t3wnUNtRso1BQPUe4BtMAxZjKqY= @@ -343,9 +342,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 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 v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/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= @@ -360,7 +357,6 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 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/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= @@ -395,7 +391,6 @@ github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pL 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/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= github.com/go-openapi/strfmt v0.21.5 h1:Z/algjpXIZpbvdN+6KbVTkpO75RuedMrqpn1GN529h4= github.com/go-openapi/strfmt v0.21.5/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= @@ -419,7 +414,6 @@ github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPr github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -708,8 +702,6 @@ 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -764,7 +756,6 @@ github.com/maxatome/go-testdeep v1.13.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwU 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/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= @@ -1117,7 +1108,6 @@ go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQa 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.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= @@ -1169,13 +1159,6 @@ golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPh 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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1184,8 +1167,6 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= From d18abe5f39c046628a5ce64c93f96d23b944708d Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 27 Jun 2023 16:28:09 +0100 Subject: [PATCH 149/154] [AWS] Adjust TTL for alias records --- provider/aws/aws.go | 4 ++++ provider/aws/aws_test.go | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index be1997c7ed..89c06bd772 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -684,6 +684,10 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoin } if alias { + if ep.RecordTTL.IsConfigured() { + log.Debugf("Modifying endpoint: %v, setting ttl=%v", ep, recordTTL) + ep.RecordTTL = recordTTL + } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok { if prop != "true" && prop != "false" { ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, "false") diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 4ed172d98b..5aa987be2c 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -523,7 +523,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { records := []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com"), - endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"), + endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 60, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health @@ -534,7 +534,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"), - endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 300,"alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health From bbeb167e2092fd4a6445c64e940ab44e8cab7fb9 Mon Sep 17 00:00:00 2001 From: Sewci0 Date: Tue, 27 Jun 2023 17:20:02 +0100 Subject: [PATCH 150/154] Update provider/aws/aws_test.go Co-authored-by: John Gardiner Myers --- provider/aws/aws_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 5aa987be2c..cce21e66a8 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -534,7 +534,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"), - endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 300,"alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 300, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health From 0019d158dc448f8987285ef49b90432af5e91cee Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 27 Jun 2023 17:42:59 +0100 Subject: [PATCH 151/154] Unset instead --- provider/aws/aws.go | 4 ++-- provider/aws/aws_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 89c06bd772..234d2093c8 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -685,8 +685,8 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoin if alias { if ep.RecordTTL.IsConfigured() { - log.Debugf("Modifying endpoint: %v, setting ttl=%v", ep, recordTTL) - ep.RecordTTL = recordTTL + log.Debugf("Modifying endpoint: %v, unsetting TTL", ep) + ep.RecordTTL = 0 } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok { if prop != "true" && prop != "false" { diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index cce21e66a8..6aaca74ca3 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -534,7 +534,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"), - endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 300, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health From ce192181fbee78f43f9cc9537e8a336403ee4a02 Mon Sep 17 00:00:00 2001 From: Seweryn Chlewicki Date: Tue, 27 Jun 2023 21:07:40 +0100 Subject: [PATCH 152/154] Revert to recordTTL --- provider/aws/aws.go | 4 ++-- provider/aws/aws_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 234d2093c8..89c06bd772 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -685,8 +685,8 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoin if alias { if ep.RecordTTL.IsConfigured() { - log.Debugf("Modifying endpoint: %v, unsetting TTL", ep) - ep.RecordTTL = 0 + log.Debugf("Modifying endpoint: %v, setting ttl=%v", ep, recordTTL) + ep.RecordTTL = recordTTL } if prop, ok := ep.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok { if prop != "true" && prop != "false" { diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 6aaca74ca3..cce21e66a8 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -534,7 +534,7 @@ func TestAWSAdjustEndpoints(t *testing.T) { validateEndpoints(t, provider, records, []*endpoint.Endpoint{ endpoint.NewEndpoint("a-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8"), endpoint.NewEndpoint("cname-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithProviderSpecific(providerSpecificAlias, "false"), - endpoint.NewEndpoint("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpointWithTTL("cname-test-alias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, 300, "alias-target.zone-2.ext-dns-test-2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-no-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "false"), endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health From 5d2cc2e59a7f80dffad028c7e18ce53796697788 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Tue, 27 Jun 2023 17:14:07 -0700 Subject: [PATCH 153/154] Suppress dependabot updates for OpenShift --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 71cf5da00d..b537898579 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,6 +13,9 @@ updates: dev-dependencies: patterns: - "*" + ignore: + - dependency-name: "github.com/openshift/api" + - dependency-name: "github.com/openshift/client-go" - package-ecosystem: "github-actions" directory: "/" schedule: From 440f513edb9ae89b61f3e61d8f688fc3e4c59798 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Wed, 28 Jun 2023 12:32:32 +0200 Subject: [PATCH 154/154] Added traefik-proxy rules to helm chart (#3325) * Added traefik-proxy rules to helm chart * Added new Traefik api group to chart Signed-off-by: Thomas Kosiewski * Added changelog entry Signed-off-by: Thomas Kosiewski --------- Signed-off-by: Thomas Kosiewski Signed-off-by: Thomas Kosiewski --- charts/external-dns/CHANGELOG.md | 1 + charts/external-dns/templates/clusterrole.yaml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/charts/external-dns/CHANGELOG.md b/charts/external-dns/CHANGELOG.md index a8617cd6bb..5c18948e0d 100644 --- a/charts/external-dns/CHANGELOG.md +++ b/charts/external-dns/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### All Changes - Disallowed privilege escalation in container security context and set the seccomp profile type to `RuntimeDefault`. ([#3689](https://github.com/kubernetes-sigs/external-dns/pull/3689)) [@nrvnrvn](https://github.com/nrvnrvn) +- Added RBAC for Traefik to ClusterRole. ([#3325](https://github.com/kubernetes-sigs/external-dns/pull/3325)) [@ThomasK33](https://github.com/thomask33) ## [v1.13.0] - 2023-03-30 diff --git a/charts/external-dns/templates/clusterrole.yaml b/charts/external-dns/templates/clusterrole.yaml index 4f33c1146c..11852f1cf4 100644 --- a/charts/external-dns/templates/clusterrole.yaml +++ b/charts/external-dns/templates/clusterrole.yaml @@ -105,6 +105,11 @@ rules: resources: ["tcpingresses"] verbs: ["get","watch","list"] {{- end }} +{{- if has "traefik-proxy" .Values.sources }} + - apiGroups: ["traefik.containo.us", "traefik.io"] + resources: ["ingressroutes", "ingressroutetcps", "ingressrouteudps"] + verbs: ["get","watch","list"] +{{- end }} {{- if has "openshift-route" .Values.sources }} - apiGroups: ["route.openshift.io"] resources: ["routes"]