diff --git a/api/v1beta1/gslb_types.go b/api/v1beta1/gslb_types.go index c083f52afe..e074ec7775 100644 --- a/api/v1beta1/gslb_types.go +++ b/api/v1beta1/gslb_types.go @@ -44,7 +44,9 @@ type Strategy struct { // +k8s:openapi-gen=true type GslbSpec struct { // Gslb-enabled Ingress Spec - Ingress IngressSpec `json:"ingress"` + Ingress *IngressSpec `json:"ingress,omitempty"` + // Gslb-enabled LoadBalancer Service + LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"` // Gslb Strategy spec Strategy Strategy `json:"strategy"` } diff --git a/api/v1beta1/upstream_types.go b/api/v1beta1/upstream_types.go index 64ce33c7f4..99d3c1b90c 100644 --- a/api/v1beta1/upstream_types.go +++ b/api/v1beta1/upstream_types.go @@ -146,6 +146,17 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { } } +// LoadBalancer defines the desired state of Gslb +// +k8s:openapi-gen=true +type LoadBalancer struct { + // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // This is the host name to be used as global domain name while creating GSLB records. + Host string `json:"host"` + // ServiceName is the name of the Service resource being exposed. + // Only LoadBalancer Service type is supported. + ServiceName string `json:"serviceName"` +} + // DeepCopyInto copying the receiver, writing into out. in must be non-nil. func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = *in @@ -163,7 +174,7 @@ func (in *IngressRuleValue) DeepCopyInto(out *IngressRuleValue) { } // FromV1IngressSpec transforms from networking.k8s.io/v1 IngressSpec to custom k8gb ingress Spec -func FromV1IngressSpec(v1Spec netv1.IngressSpec) IngressSpec { +func FromV1IngressSpec(v1Spec netv1.IngressSpec) *IngressSpec { spec := IngressSpec{} spec.DefaultBackend = v1Spec.DefaultBackend spec.IngressClassName = v1Spec.IngressClassName @@ -177,7 +188,7 @@ func FromV1IngressSpec(v1Spec netv1.IngressSpec) IngressSpec { } spec.Rules = append(spec.Rules, rule) } - return spec + return &spec } // ToV1IngressSpec transforms from k8gb ingress Spec to networking.k8s.io/v1 IngressSpec diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index a6b00336fd..f97254001b 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -89,7 +89,15 @@ func (in *GslbList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GslbSpec) DeepCopyInto(out *GslbSpec) { *out = *in - in.Ingress.DeepCopyInto(&out.Ingress) + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = (*in).DeepCopy() + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancer) + **out = **in + } in.Strategy.DeepCopyInto(&out.Strategy) } @@ -170,6 +178,21 @@ func (in *IngressSpec) DeepCopy() *IngressSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer. +func (in *LoadBalancer) DeepCopy() *LoadBalancer { + if in == nil { + return nil + } + out := new(LoadBalancer) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Strategy) DeepCopyInto(out *Strategy) { *out = *in diff --git a/chart/k8gb/crd/k8gb.absa.oss_gslbs.yaml b/chart/k8gb/crd/k8gb.absa.oss_gslbs.yaml index 05c67224f0..b9b8d57fad 100644 --- a/chart/k8gb/crd/k8gb.absa.oss_gslbs.yaml +++ b/chart/k8gb/crd/k8gb.absa.oss_gslbs.yaml @@ -307,6 +307,22 @@ spec: type: object type: array type: object + loadBalancer: + description: Gslb-enabled LoadBalancer Service + properties: + host: + description: Host is the fully qualified domain name of a network + host, as defined by RFC 3986. This is the host name to be used + as global domain name while creating GSLB records. + type: string + serviceName: + description: ServiceName is the name of the Service resource being + exposed. Only LoadBalancer Service type is supported. + type: string + required: + - host + - serviceName + type: object strategy: description: Gslb Strategy spec properties: @@ -331,7 +347,6 @@ spec: - type type: object required: - - ingress - strategy type: object status: diff --git a/controllers/dnsupdate.go b/controllers/dnsupdate.go index 524726af6e..43507cfb88 100644 --- a/controllers/dnsupdate.go +++ b/controllers/dnsupdate.go @@ -43,9 +43,19 @@ func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb) (*externaldns.D return nil, err } - localTargets, err := r.DNSProvider.GslbIngressExposedIPs(gslb) - if err != nil { - return nil, err + localTargets := []string{} + if gslb.Spec.Ingress != nil { + localTargets, err = r.DNSProvider.GslbIngressExposedIPs(gslb) + if err != nil { + return nil, err + } + } + + if gslb.Spec.LoadBalancer != nil { + localTargets, err = r.DNSProvider.GslbServiceExposedIPs(gslb) + if err != nil { + return nil, err + } } for host, health := range serviceHealth { diff --git a/controllers/gslb_controller_reconciliation.go b/controllers/gslb_controller_reconciliation.go index d869048351..cee9748456 100644 --- a/controllers/gslb_controller_reconciliation.go +++ b/controllers/gslb_controller_reconciliation.go @@ -137,16 +137,18 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. } // == Ingress ========== - ingress, err := r.gslbIngress(gslb) - if err != nil { - m.IncrementError(gslb) - return result.RequeueError(err) - } + if gslb.Spec.Ingress != nil { + ingress, err := r.gslbIngress(gslb) + if err != nil { + m.IncrementError(gslb) + return result.RequeueError(err) + } - err = r.saveIngress(gslb, ingress) - if err != nil { - m.IncrementError(gslb) - return result.RequeueError(err) + err = r.saveIngress(gslb, ingress) + if err != nil { + m.IncrementError(gslb) + return result.RequeueError(err) + } } // == external-dns dnsendpoints CRs == diff --git a/controllers/gslb_controller_setup.go b/controllers/gslb_controller_setup.go index 6f58c7206e..e6ab1b195e 100644 --- a/controllers/gslb_controller_setup.go +++ b/controllers/gslb_controller_setup.go @@ -57,13 +57,18 @@ func (r *GslbReconciler) SetupWithManager(mgr ctrl.Manager) error { } gslbName := "" for _, gslb := range gslbList.Items { - for _, rule := range gslb.Spec.Ingress.Rules { - for _, path := range rule.HTTP.Paths { - if path.Backend.Service != nil && path.Backend.Service.Name == a.GetName() { - gslbName = gslb.Name + if gslb.Spec.Ingress != nil { + for _, rule := range gslb.Spec.Ingress.Rules { + for _, path := range rule.HTTP.Paths { + if path.Backend.Service != nil && path.Backend.Service.Name == a.GetName() { + gslbName = gslb.Name + } } } } + if gslb.Spec.LoadBalancer != nil && gslb.Spec.LoadBalancer.ServiceName == a.GetName() { + gslbName = gslb.Name + } } if len(gslbName) > 0 { return []reconcile.Request{ diff --git a/controllers/ingress.go b/controllers/ingress.go index 67fc315ea9..817fd3e2ed 100644 --- a/controllers/ingress.go +++ b/controllers/ingress.go @@ -43,7 +43,7 @@ func (r *GslbReconciler) gslbIngress(gslb *k8gbv1beta1.Gslb) (*netv1.Ingress, er Namespace: gslb.Namespace, Annotations: gslb.Annotations, }, - Spec: k8gbv1beta1.ToV1IngressSpec(gslb.Spec.Ingress), + Spec: k8gbv1beta1.ToV1IngressSpec(*gslb.Spec.Ingress), } err := controllerutil.SetControllerReference(gslb, ingress, r.Scheme) diff --git a/controllers/mocks/assistant_mock.go b/controllers/mocks/assistant_mock.go index db332ed33d..4f2605f161 100644 --- a/controllers/mocks/assistant_mock.go +++ b/controllers/mocks/assistant_mock.go @@ -93,12 +93,27 @@ func (m *MockAssistant) GslbIngressExposedIPs(gslb *v1beta1.Gslb) ([]string, err return ret0, ret1 } +// GslbServiceExposedIPs mocks base method. +func (m *MockAssistant) GslbServiceExposedIPs(gslb *v1beta1.Gslb) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GslbServiceExposedIPs", gslb) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // GslbIngressExposedIPs indicates an expected call of GslbIngressExposedIPs. func (mr *MockAssistantMockRecorder) GslbIngressExposedIPs(gslb interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GslbIngressExposedIPs", reflect.TypeOf((*MockAssistant)(nil).GslbIngressExposedIPs), gslb) } +// GslbServiceExposedIPs indicates an expected call of GslbServiceExposedIPs. +func (mr *MockAssistantMockRecorder) GslbServiceExposedIPs(gslb interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GslbServiceExposedIPs", reflect.TypeOf((*MockAssistant)(nil).GslbIngressExposedIPs), gslb) +} + // InspectTXTThreshold mocks base method. func (m *MockAssistant) InspectTXTThreshold(fqdn string, splitBrainThreshold time.Duration) error { m.ctrl.T.Helper() diff --git a/controllers/mocks/provider_mock.go b/controllers/mocks/provider_mock.go index b98bb21d46..9f9850213f 100644 --- a/controllers/mocks/provider_mock.go +++ b/controllers/mocks/provider_mock.go @@ -105,12 +105,27 @@ func (m *MockProvider) GslbIngressExposedIPs(arg0 *v1beta1.Gslb) ([]string, erro return ret0, ret1 } +// GslbServiceExposedIPs mocks base method. +func (m *MockProvider) GslbServiceExposedIPs(arg0 *v1beta1.Gslb) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GslbServiceExposedIPs", arg0) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // GslbIngressExposedIPs indicates an expected call of GslbIngressExposedIPs. func (mr *MockProviderMockRecorder) GslbIngressExposedIPs(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GslbIngressExposedIPs", reflect.TypeOf((*MockProvider)(nil).GslbIngressExposedIPs), arg0) } +// GslbServiceExposedIPs indicates an expected call of GslbServiceExposedIPs. +func (mr *MockProviderMockRecorder) GslbServiceExposedIPs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GslbServiceExposedIPs", reflect.TypeOf((*MockProvider)(nil).GslbIngressExposedIPs), arg0) +} + // SaveDNSEndpoint mocks base method. func (m *MockProvider) SaveDNSEndpoint(arg0 *v1beta1.Gslb, arg1 *endpoint.DNSEndpoint) error { m.ctrl.T.Helper() diff --git a/controllers/providers/assistant/assistant.go b/controllers/providers/assistant/assistant.go index 1471a33560..b53b352e91 100644 --- a/controllers/providers/assistant/assistant.go +++ b/controllers/providers/assistant/assistant.go @@ -30,6 +30,8 @@ type Assistant interface { CoreDNSExposedIPs() ([]string, error) // GslbIngressExposedIPs retrieves list of IP's exposed by all GSLB ingresses GslbIngressExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) + // GslbServiceExposedIPs retrieves list of IP's exposed by all GSLB LoadBalancer type Services + GslbServiceExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) // GetExternalTargets retrieves slice of targets from external clusters GetExternalTargets(host string, extClusterNsNames map[string]string) (targets Targets) // SaveDNSEndpoint update DNS endpoint or create new one if doesnt exist diff --git a/controllers/providers/assistant/gslb.go b/controllers/providers/assistant/gslb.go index 6797098f38..bded7d4cfb 100644 --- a/controllers/providers/assistant/gslb.go +++ b/controllers/providers/assistant/gslb.go @@ -158,6 +158,47 @@ func (r *Gslb) GslbIngressExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) { return gslbIngressIPs, nil } +// GslbServiceExposedIPs retrieves list of IP's exposed by all GSLB LoadBalancer type services +func (r *Gslb) GslbServiceExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) { + nn := types.NamespacedName{ + Name: gslb.Spec.LoadBalancer.ServiceName, + Namespace: gslb.Namespace, + } + + gslbService := &corev1.Service{} + + err := r.client.Get(context.TODO(), nn, gslbService) + if err != nil { + if errors.IsNotFound(err) { + log.Info(). + Str("gslb", gslb.Spec.LoadBalancer.ServiceName). + Msg("Can't find gslb Service") + } + return nil, err + } + + if gslbService.Spec.Type != corev1.ServiceTypeLoadBalancer { + return nil, fmt.Errorf("service %s is not of type LoadBalancer", gslb.Spec.LoadBalancer.ServiceName) + } + + var gslbServiceIPs []string + for _, ip := range gslbService.Status.LoadBalancer.Ingress { + if len(ip.IP) > 0 { + gslbServiceIPs = append(gslbServiceIPs, ip.IP) + } + if len(ip.Hostname) > 0 { + IPs, err := utils.Dig(ip.Hostname, r.edgeDNSServers...) + if err != nil { + log.Warn().Err(err).Msg("Dig error") + return nil, err + } + gslbServiceIPs = append(gslbServiceIPs, IPs...) + } + } + + return gslbServiceIPs, nil +} + // SaveDNSEndpoint update DNS endpoint or create new one if doesnt exist func (r *Gslb) SaveDNSEndpoint(namespace string, i *externaldns.DNSEndpoint) error { found := &externaldns.DNSEndpoint{} diff --git a/controllers/providers/dns/dns.go b/controllers/providers/dns/dns.go index 55f90b5bf3..f6c9a5f77e 100644 --- a/controllers/providers/dns/dns.go +++ b/controllers/providers/dns/dns.go @@ -29,6 +29,8 @@ type Provider interface { CreateZoneDelegationForExternalDNS(*k8gbv1beta1.Gslb) error // GslbIngressExposedIPs retrieves list of IP's exposed by all GSLB ingresses GslbIngressExposedIPs(*k8gbv1beta1.Gslb) ([]string, error) + // GslbServiceExposedIPs retrieves list of IP's exposed by all LoadBalancer type Services + GslbServiceExposedIPs(*k8gbv1beta1.Gslb) ([]string, error) // GetExternalTargets retrieves list of external targets for specified host GetExternalTargets(string) assistant.Targets // SaveDNSEndpoint update DNS endpoint in gslb or create new one if doesn't exist diff --git a/controllers/providers/dns/empty.go b/controllers/providers/dns/empty.go index 0a3c67d395..dc0ce369a1 100644 --- a/controllers/providers/dns/empty.go +++ b/controllers/providers/dns/empty.go @@ -46,6 +46,10 @@ func (p *EmptyDNSProvider) GslbIngressExposedIPs(gslb *k8gbv1beta1.Gslb) (r []st return p.assistant.GslbIngressExposedIPs(gslb) } +func (p *EmptyDNSProvider) GslbServiceExposedIPs(gslb *k8gbv1beta1.Gslb) (r []string, err error) { + return p.assistant.GslbServiceExposedIPs(gslb) +} + func (p *EmptyDNSProvider) GetExternalTargets(host string) (targets assistant.Targets) { return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames()) } diff --git a/controllers/providers/dns/external.go b/controllers/providers/dns/external.go index 66673cb62c..72599745a4 100644 --- a/controllers/providers/dns/external.go +++ b/controllers/providers/dns/external.go @@ -113,6 +113,10 @@ func (p *ExternalDNSProvider) GslbIngressExposedIPs(gslb *k8gbv1beta1.Gslb) ([]s return p.assistant.GslbIngressExposedIPs(gslb) } +func (p *ExternalDNSProvider) GslbServiceExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) { + return p.assistant.GslbServiceExposedIPs(gslb) +} + func (p *ExternalDNSProvider) SaveDNSEndpoint(gslb *k8gbv1beta1.Gslb, i *externaldns.DNSEndpoint) error { return p.assistant.SaveDNSEndpoint(gslb.Namespace, i) } diff --git a/controllers/providers/dns/infoblox.go b/controllers/providers/dns/infoblox.go index c5eab7de31..104bc44004 100644 --- a/controllers/providers/dns/infoblox.go +++ b/controllers/providers/dns/infoblox.go @@ -210,6 +210,10 @@ func (p *InfobloxProvider) GslbIngressExposedIPs(gslb *k8gbv1beta1.Gslb) ([]stri return p.assistant.GslbIngressExposedIPs(gslb) } +func (p *InfobloxProvider) GslbServiceExposedIPs(gslb *k8gbv1beta1.Gslb) ([]string, error) { + return p.assistant.GslbServiceExposedIPs(gslb) +} + func (p *InfobloxProvider) SaveDNSEndpoint(gslb *k8gbv1beta1.Gslb, i *externaldns.DNSEndpoint) error { return p.assistant.SaveDNSEndpoint(gslb.Namespace, i) } diff --git a/controllers/status.go b/controllers/status.go index d7b6d29527..76a8862add 100644 --- a/controllers/status.go +++ b/controllers/status.go @@ -59,53 +59,71 @@ func (r *GslbReconciler) updateGslbStatus(gslb *k8gbv1beta1.Gslb, ep *externaldn func (r *GslbReconciler) getServiceHealthStatus(gslb *k8gbv1beta1.Gslb) (map[string]k8gbv1beta1.HealthStatus, error) { serviceHealth := make(map[string]k8gbv1beta1.HealthStatus) - for _, rule := range gslb.Spec.Ingress.Rules { - for _, path := range rule.HTTP.Paths { - if path.Backend.Service == nil || path.Backend.Service.Name == "" { - log.Warn(). - Str("gslb", gslb.Name). - Interface("service", path.Backend.Service). - Msg("Malformed service definition") - serviceHealth[rule.Host] = k8gbv1beta1.NotFound - continue - } - service := &corev1.Service{} - finder := client.ObjectKey{ - Namespace: gslb.Namespace, - Name: path.Backend.Service.Name, - } - err := r.Get(context.TODO(), finder, service) - if err != nil { - if errors.IsNotFound(err) { + if gslb.Spec.Ingress != nil { + for _, rule := range gslb.Spec.Ingress.Rules { + for _, path := range rule.HTTP.Paths { + if path.Backend.Service == nil || path.Backend.Service.Name == "" { + log.Warn(). + Str("gslb", gslb.Name). + Interface("service", path.Backend.Service). + Msg("Malformed service definition") serviceHealth[rule.Host] = k8gbv1beta1.NotFound continue } - return serviceHealth, err + err := r.populateServiceHealth(serviceHealth, path.Backend.Service.Name, gslb.Namespace, rule.Host) + if errors.IsNotFound(err) { + continue + } } + } + } - endpoints := &corev1.Endpoints{} + if gslb.Spec.LoadBalancer != nil { + err := r.populateServiceHealth(serviceHealth, gslb.Spec.LoadBalancer.ServiceName, gslb.Namespace, gslb.Spec.LoadBalancer.Host) + if err != nil { + return nil, err + } + } - nn := types.NamespacedName{ - Name: path.Backend.Service.Name, - Namespace: gslb.Namespace, - } + return serviceHealth, nil +} - err = r.Get(context.TODO(), nn, endpoints) - if err != nil { - return serviceHealth, err - } +func (r *GslbReconciler) populateServiceHealth(serviceHealth map[string]k8gbv1beta1.HealthStatus, name, namespace, host string) error { + service := &corev1.Service{} + finder := client.ObjectKey{ + Namespace: namespace, + Name: name, + } + err := r.Get(context.TODO(), finder, service) + if err != nil { + if errors.IsNotFound(err) { + serviceHealth[host] = k8gbv1beta1.NotFound + } + return err + } - serviceHealth[rule.Host] = k8gbv1beta1.Unhealthy - if len(endpoints.Subsets) > 0 { - for _, subset := range endpoints.Subsets { - if len(subset.Addresses) > 0 { - serviceHealth[rule.Host] = k8gbv1beta1.Healthy - } - } + endpoints := &corev1.Endpoints{} + + nn := types.NamespacedName{ + Name: name, + Namespace: namespace, + } + + err = r.Get(context.TODO(), nn, endpoints) + if err != nil { + return err + } + + serviceHealth[host] = k8gbv1beta1.Unhealthy + if len(endpoints.Subsets) > 0 { + for _, subset := range endpoints.Subsets { + if len(subset.Addresses) > 0 { + serviceHealth[host] = k8gbv1beta1.Healthy } } } - return serviceHealth, nil + + return nil } func (r *GslbReconciler) getHealthyRecords(gslb *k8gbv1beta1.Gslb) (map[string][]string, error) { @@ -139,8 +157,13 @@ func (r *GslbReconciler) getHealthyRecords(gslb *k8gbv1beta1.Gslb) (map[string][ func (r *GslbReconciler) hostsToCSV(gslb *k8gbv1beta1.Gslb) string { var hosts []string - for _, r := range gslb.Spec.Ingress.Rules { - hosts = append(hosts, r.Host) + if gslb.Spec.Ingress != nil { + for _, r := range gslb.Spec.Ingress.Rules { + hosts = append(hosts, r.Host) + } + } + if gslb.Spec.LoadBalancer != nil { + hosts = append(hosts, gslb.Spec.LoadBalancer.Host) } return strings.Join(hosts, ", ") } diff --git a/go.sum b/go.sum index 67c071a7d1..3c8f719ee9 100644 --- a/go.sum +++ b/go.sum @@ -387,6 +387,12 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +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= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -499,6 +505,14 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -507,6 +521,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/terratest/utils/extensions.go b/terratest/utils/extensions.go index c0901fa693..47e1b34614 100644 --- a/terratest/utils/extensions.go +++ b/terratest/utils/extensions.go @@ -21,7 +21,6 @@ Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic import ( "encoding/json" "fmt" - "github.com/gruntwork-io/terratest/modules/retry" "os" "path/filepath" "strconv" @@ -29,6 +28,8 @@ import ( "testing" "time" + "github.com/gruntwork-io/terratest/modules/retry" + "github.com/AbsaOSS/gopkg/dns" gopkgstr "github.com/AbsaOSS/gopkg/string" "github.com/gruntwork-io/terratest/modules/helm"