From 844b787dba8ca79cf2a62995aea20aef5935c401 Mon Sep 17 00:00:00 2001 From: kbhandari Date: Thu, 7 May 2020 18:28:47 +0530 Subject: [PATCH 1/8] Started making changes on ultradns plugin --- .github/labeler.yml | 3 +++ README.md | 2 ++ docs/ttl.md | 4 ++++ main.go | 4 ++++ pkg/apis/externaldns/types.go | 2 +- 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 0274c9d9d..e0dc68118 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -64,3 +64,6 @@ provider/vinyldns: provider/vinyldns* # Add 'provider/vultr' in file which starts with vultr provider/vultr: provider/vultr* + +# Add 'provider/ultradns' in file which starts with vultr +provider/vultr: provider/ultradns* diff --git a/README.md b/README.md index 5f1431445..9aa2553e8 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ The following table clarifies the current status of the providers according to t | Akamai FastDNS | Alpha | | | OVH | Alpha | | | Vultr | Alpha | | +| UltraDNS | Alpha | | ## Running ExternalDNS: @@ -144,6 +145,7 @@ The following tutorials are provided: * [VinylDNS](docs/tutorials/vinyldns.md) * [OVH](docs/tutorials/ovh.md) * [Vultr](docs/tutorials/vultr.md) +* [UltraDNS](docs/tutorials/ultradns.md) ### Running Locally diff --git a/docs/ttl.md b/docs/ttl.md index 8e5df4e0f..db1cc15e0 100644 --- a/docs/ttl.md +++ b/docs/ttl.md @@ -45,6 +45,7 @@ Providers - [x] TransIP - [x] RFC2136 - [x] Vultr +- [x] UltraDNS PRs welcome! @@ -76,3 +77,6 @@ The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 6 ### Vultr Provider The Vultr provider minimal TTL is used when the TTL is 0. The default is 1 hour. + +### UltraDNS +The UltraDNS provider minimal TTL is used when the TTL is 0. The default is 24 hour. diff --git a/main.go b/main.go index a09e21d47..e8c0ef5d8 100644 --- a/main.go +++ b/main.go @@ -167,6 +167,10 @@ func main() { p, err = provider.NewVinylDNSProvider(domainFilter, zoneIDFilter, cfg.DryRun) case "vultr": p, err = provider.NewVultrProvider(domainFilter, cfg.DryRun) + + case "ultradns": + p, err = provider.NewUltraDNSProvider(domainFilter, cfg.DryRun) + case "cloudflare": p, err = provider.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareZonesPerPage, cfg.CloudflareProxied, cfg.DryRun) case "rcodezero": diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 385427d9d..7ffb95a17 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -312,7 +312,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter) // Flags related to providers - app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr") + app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr") app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) From db3fdfb1d9f169ce76db85c5b945f3da20ccd2ce Mon Sep 17 00:00:00 2001 From: kbhandari Date: Mon, 11 May 2020 13:42:47 +0530 Subject: [PATCH 2/8] Finalized version of ultradns provider --- .github/labeler.yml | 4 +- docs/tutorials/ultradns.md | 619 ++++++++++++++++++++++++++++++ go.mod | 4 +- go.sum | 36 +- main.go | 2 +- pkg/apis/externaldns/types.go | 2 +- provider/ultradns.go | 511 +++++++++++++++++++++++++ provider/ultradns_test.go | 686 ++++++++++++++++++++++++++++++++++ 8 files changed, 1832 insertions(+), 32 deletions(-) create mode 100644 docs/tutorials/ultradns.md create mode 100644 provider/ultradns.go create mode 100644 provider/ultradns_test.go diff --git a/.github/labeler.yml b/.github/labeler.yml index e0dc68118..f831d8422 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -65,5 +65,5 @@ provider/vinyldns: provider/vinyldns* # Add 'provider/vultr' in file which starts with vultr provider/vultr: provider/vultr* -# Add 'provider/ultradns' in file which starts with vultr -provider/vultr: provider/ultradns* +# Add 'provider/ultradns' in file which starts with ultradns +provider/ultradns: provider/ultradns* diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md new file mode 100644 index 000000000..86d39d9ef --- /dev/null +++ b/docs/tutorials/ultradns.md @@ -0,0 +1,619 @@ +# Setting up ExternalDNS for Services on UltraDNS + +This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using UltraDNS. + +For this tutorial, please make sure that you are using a version **> 0.7.2** of ExternalDNS. + +## Managing DNS with UltraDNS + +If you would like to read-up on the UltraDNS service, you can find additional details here: [Introduction to UltraDNS](https://docs.ultradns.neustar) + +Before proceeding, please create a new DNS Zone that you will create your records in for this tutorial process. For the examples in this tutorial, we will be using `example.com` as our Zone. + +## Setting Up UltraDNS Credentials + +The following environment variables will be needed to run ExternalDNS with UltraDNS. + +`ULTRADNS_USERNAME`,`ULTRADNS_PASSWORD`, &`ULTRADNS_BASEURL` +`ULTRADNS_ACCOUNTNAME`(optional variable). + +## Deploying ExternalDNS + +Connect your `kubectl` client to the cluster you want to test ExternalDNS with. +Then, apply one of the following manifests file to deploy ExternalDNS. + +- Note: We are assuming the zone is already present within UltraDNS. +- Note: While creating CNAMES as target endpoints, the `--txt-prefix` option is mandatory. +### 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 + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service + - --source=ingress # ingress is also possible + - --domain-filter=example.com # (Recommended) We recommend to use this filter as it minimize the time to propagate changes, as there are less number of zones to look into.. + - --provider=ultradns + - --txt-prefix=txt- + env: + - name: ULTRADNS_USERNAME + value: "" + - name: ULTRADNS_PASSWORD # The password is required to be BASE64 encrypted. + value: "" + - name: ULTRADNS_BASEURL + value: "https://api.ultradns.com/" + - name: ULTRADNS_ACCOUNTNAME + value: "" +``` + +### Manifest (for clusters with RBAC enabled) + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: external-dns +rules: +- apiGroups: [""] + resources: ["services","endpoints","pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["list"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +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 + image: registry.opensource.zalan.do/teapot/external-dns:latest + args: + - --source=service + - --source=ingress + - --domain-filter=example.com #(Recommended) We recommend to use this filter as it minimize the time to propagate changes, as there are less number of zones to look into.. + - --provider=ultradns + - --txt-prefix=txt- + env: + - name: ULTRADNS_USERNAME + value: "" + - name: ULTRADNS_PASSWORD # The password is required to be BASE64 encrypted. + value: "" + - name: ULTRADNS_BASEURL + value: "https://api.ultradns.com/" + - name: ULTRADNS_ACCOUNTNAME + value: "" +``` + +## Deploying an Nginx Service + +Create a service file called 'nginx.yaml' with the following contents: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx +spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx + annotations: + external-dns.alpha.kubernetes.io/hostname: my-app.example.com. +spec: + selector: + app: nginx + type: LoadBalancer + ports: + - protocol: TCP + port: 80 + targetPort: 80 +``` + +Please note the annotation on the service. Use the same hostname as the UltraDNS zone created above. + +ExternalDNS uses this annotation to determine what services should be registered with DNS. Removing the annotation will cause ExternalDNS to remove the corresponding DNS records. + +## Creating the Deployment and Service: + +```console +$ kubectl create -f nginx.yaml +$ kubectl create -f external-dns.yaml +``` + +Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service. + +Once the service has an external IP assigned, ExternalDNS will notice the new service IP address and will synchronize the UltraDNS records. + +## Verifying UltraDNS Records + +Please verify on the [UltraDNS UI](https://portal.ultradns.neustar) that the records are created under the zone "example.com". + +For more information on UltraDNS UI, refer to (https://docs.ultradns.neustar/mspuserguide.html). + +Select the zone that was created above (or select the appropriate zone if a different zone was used.) + +The external IP address will be displayed as a CNAME record for your zone. + +## Cleaning Up the Deployment and Service + +Now that we have verified that ExternalDNS will automatically manage your UltraDNS records, you can delete example zones that you created in this tutorial: + +``` +$ kubectl delete service -f nginx.yaml +$ kubectl delete service -f externaldns.yaml +``` +## Creating Multiple A Records Target +- First, you want to create a service file called 'apple-banana-echo.yaml' +```yaml +--- +kind: Pod +apiVersion: v1 +metadata: + name: apple-app + labels: + app: apple +spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" +--- +kind: Service +apiVersion: v1 +metadata: + name: apple-service +spec: + selector: + app: apple + ports: + - port: 5678 # Default port for image +``` +- Then, create service file called 'expose-apple-banana-app.yaml' to expose the services. For more information to deploy ingress controller, refer to (https://kubernetes.github.io/ingress-nginx/deploy/) +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: example-ingress + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple.example.com. + external-dns.alpha.kubernetes.io/target: 10.10.10.1,10.10.10.23 +spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service + servicePort: 5678 +``` +- Then, create the deployment and service: +```console +$ kubectl create -f apple-banana-echo.yaml +$ kubectl create -f expose-apple-banana-app.yaml +$ kubectl create -f external-dns.yaml +``` +- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service. +- Please verify on the [UltraDNS UI](https://portal.ultradns.neustar) that the records have been created under the zone "example.com". +- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone ‘example.com’: +```console +$ kubectl delete -f apple-banana-echo.yaml +$ kubectl delete -f expose-apple-banana-app.yaml +$ kubectl delete -f external-dns.yaml +``` +## Creating CNAME Record +- Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. If this not provided, your records will not be created. +- First, create a service file called 'apple-banana-echo.yaml' + - _Config File Example – kubernetes cluster is on-premise not on cloud_ + ```yaml + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app + labels: + app: apple + spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service + spec: + selector: + app: apple + ports: + - port: 5678 # Default port for image + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple.example.com. + external-dns.alpha.kubernetes.io/target: apple.cname.com. + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service + servicePort: 5678 + ``` + - _Config File Example – Kubernetes cluster service from different cloud vendors_ + ```yaml + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app + labels: + app: apple + spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service + annotations: + external-dns.alpha.kubernetes.io/hostname: my-app.example.com. + spec: + selector: + app: apple + type: LoadBalancer + ports: + - protocol: TCP + port: 5678 + targetPort: 5678 + ``` +- Then, create the deployment and service: +```console +$ kubectl create -f apple-banana-echo.yaml +$ kubectl create -f external-dns.yaml +``` +- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service. +- Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com". +- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone "example.com": +```console +$ kubectl delete -f apple-banana-echo.yaml +$ kubectl delete -f external-dns.yaml +``` +## Create Multiple Types Of Records +- Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. Since you will also be created a CNAME record, If this not provided, your records will not be created. +- First, create a service file called 'apple-banana-echo.yaml' + - _Config File Example – kubernetes cluster is on-premise not on cloud_ + ```yaml + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app + labels: + app: apple + spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service + spec: + selector: + app: apple + ports: + - port: 5678 # Default port for image + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app1 + labels: + app: apple1 + spec: + containers: + - name: apple-app1 + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service1 + spec: + selector: + app: apple1 + ports: + - port: 5679 # Default port for image + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app2 + labels: + app: apple2 + spec: + containers: + - name: apple-app2 + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service2 + spec: + selector: + app: apple2 + ports: + - port: 5680 # Default port for image + apiVersion: extensions/v1beta1 + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple.example.com. + external-dns.alpha.kubernetes.io/target: apple.cname.com. + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service + servicePort: 5678 + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress1 + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple-banana.example.com. + external-dns.alpha.kubernetes.io/target: 10.10.10.3 + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service1 + servicePort: 5679 + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress2 + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: banana.example.com. + external-dns.alpha.kubernetes.io/target: 10.10.10.3,10.10.10.20 + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service2 + servicePort: 5680 + ``` + - _Config File Example – Kubernetes cluster service from different cloud vendors_ + ```yaml + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx + spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx + ports: + - containerPort: 80 + --- + apiVersion: v1 + kind: Service + metadata: + name: nginx + annotations: + external-dns.alpha.kubernetes.io/hostname: my-app.example.com. + spec: + selector: + app: nginx + type: LoadBalancer + ports: + - protocol: TCP + port: 80 + targetPort: 80 + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app + labels: + app: apple + spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service + spec: + selector: + app: apple + ports: + - port: 5678 # Default port for image + --- + kind: Pod + apiVersion: v1 + metadata: + name: apple-app1 + labels: + app: apple1 + spec: + containers: + - name: apple-app1 + image: hashicorp/http-echo + args: + - "-text=apple" + --- + kind: Service + apiVersion: v1 + metadata: + name: apple-service1 + spec: + selector: + app: apple1 + ports: + - port: 5679 # Default port for image + --- + kind: Ingress + metadata: + name: example-ingress + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple.example.com. + external-dns.alpha.kubernetes.io/target: 10.10.10.3,10.10.10.25 + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service + servicePort: 5678 + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress1 + annotations: + ingress.kubernetes.io/rewrite-target: / + ingress.kubernetes.io/scheme: internet-facing + external-dns.alpha.kubernetes.io/hostname: apple-banana.example.com. + external-dns.alpha.kubernetes.io/target: 10.10.10.3 + spec: + rules: + - http: + paths: + - path: /apple + backend: + serviceName: apple-service1 + servicePort: 5679 + ``` +- Then, create the deployment and service: +```console +$ kubectl create -f apple-banana-echo.yaml +$ kubectl create -f external-dns.yaml +``` +- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service. +-o Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com". +- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone "example.com": +```console +$ kubectl delete -f apple-banana-echo.yaml +$ kubectl delete -f external-dns.yaml``` diff --git a/go.mod b/go.mod index 88d165710..b017db91a 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/alecthomas/colour v0.1.0 // indirect github.com/alecthomas/kingpin v2.2.5+incompatible github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect + github.com/ultradns/ultradns-sdk-go v1.3.7 github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f github.com/aws/aws-sdk-go v1.27.4 github.com/cloudflare/cloudflare-go v0.10.1 @@ -28,6 +29,7 @@ require ( github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b // indirect github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f github.com/gophercloud/gophercloud v0.1.0 + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/heptio/contour v0.15.0 github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65 github.com/linki/instrumented_http v0.2.0 @@ -44,7 +46,7 @@ require ( github.com/prometheus/client_golang v1.0.0 github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0 github.com/sergi/go-diff v1.1.0 // indirect - github.com/sirupsen/logrus v1.4.2 + github.com/sirupsen/logrus v1.6.0 github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect github.com/smartystreets/gunit v1.1.1 // indirect github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index 1215b0df5..7608ffbe3 100644 --- a/go.sum +++ b/go.sum @@ -71,12 +71,10 @@ github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAK github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= 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 h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/ultradns/ultradns-sdk-go v1.3.7 h1:sGeLtpu5atyi4aXEM18aEz0DpTFyhREhCSfkx4RojfU= +github.com/ultradns/ultradns-sdk-go v1.3.7/go.mod h1:vCC5SBZUcMRpcfma80Aw0Xk11WxOgbDA071AUban7ws= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0= @@ -96,8 +94,6 @@ github.com/aws/aws-sdk-go v1.27.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= @@ -105,8 +101,6 @@ github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+ github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY= github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= @@ -194,6 +188,7 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqL github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk= 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/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= @@ -206,7 +201,6 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ini/ini v1.33.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= @@ -263,8 +257,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v15.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= @@ -345,6 +337,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= @@ -374,8 +368,6 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jteeuwen/go-bindata v0.0.0-20180305030458-6025e8de665b/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -394,6 +386,8 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo 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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= 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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -511,22 +505,16 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -534,8 +522,6 @@ github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7z github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o= github.com/prometheus/prom2json v1.2.1/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -561,6 +547,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 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= @@ -699,8 +687,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -732,8 +718,6 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -764,8 +748,6 @@ golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDq golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= diff --git a/main.go b/main.go index e8c0ef5d8..0cff80cda 100644 --- a/main.go +++ b/main.go @@ -169,7 +169,7 @@ func main() { p, err = provider.NewVultrProvider(domainFilter, cfg.DryRun) case "ultradns": - p, err = provider.NewUltraDNSProvider(domainFilter, cfg.DryRun) + p, err = provider.NewUltraDNSProvider(domainFilter, cfg.DryRun ) case "cloudflare": p, err = provider.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareZonesPerPage, cfg.CloudflareProxied, cfg.DryRun) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 7ffb95a17..a79794d06 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -312,7 +312,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter) // Flags related to providers - app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr") + app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr", "ultradns") app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains) app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter) diff --git a/provider/ultradns.go b/provider/ultradns.go new file mode 100644 index 000000000..fb1846ebb --- /dev/null +++ b/provider/ultradns.go @@ -0,0 +1,511 @@ +/* +Copyright 2020 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 provider + +import ( + "context" + "encoding/base64" + "fmt" + "os" + "strconv" + "strings" + "time" + + udnssdk "github.com/ultradns/ultradns-sdk-go" + log "github.com/sirupsen/logrus" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" +) + +const ( + ultradnsDefaultTTL = 198 + ultradnsCreate = "CREATE" + ultradnsDelete = "DELETE" + ultradnsUpdate = "UPDATE" + sbPoolPriority = 1 + sbPoolOrder = "ROUND_ROBIN" + rdPoolOrder = "ROUND_ROBIN" +) + +// global variables +var sbPoolRunProbes = true +var sbPoolActOnProbes = true +var ultradnsPoolType = "rdpool" + +//Setting custom headers for ultradns api calls +var customHeader = []udnssdk.CustomHeader{ + udnssdk.CustomHeader { + Key: "UltraClient", + Value: "kube-client", + }, +} + +type UltraDNSProvider struct { + client udnssdk.Client + + domainFilter endpoint.DomainFilter + DryRun bool + AccountName string +} + +type UltraDNSChanges struct { + Action string + + ResourceRecordSetUltraDNS udnssdk.RRSet +} + +// NewUltraDNSProvider initializes a new UltraDNS DNS based provider +func NewUltraDNSProvider(domainFilter endpoint.DomainFilter, dryRun bool) (*UltraDNSProvider, error) { + Username, ok := os.LookupEnv("ULTRADNS_USERNAME") + udnssdk.SetCustomHeader = customHeader + if !ok { + return nil, fmt.Errorf("no username found") + } + + Base64Password, ok := os.LookupEnv("ULTRADNS_PASSWORD") + if !ok { + return nil, fmt.Errorf("no password found") + } + + // Base64 Standard Decoding + Password, err := base64.StdEncoding.DecodeString(Base64Password) + if err != nil { + fmt.Printf("Error decoding string: %s ", err.Error()) + return nil, err + } + + BaseURL, ok := os.LookupEnv("ULTRADNS_BASEURL") + if !ok { + return nil, fmt.Errorf("no baseurl found") + } + AccountName, ok := os.LookupEnv("ULTRADNS_ACCOUNTNAME") + if !ok { + AccountName = "" + } + + probeValue, ok := os.LookupEnv("ULTRADNS_ENABLE_PROBING") + if ok { + if (probeValue != "true") && (probeValue != "false") { + return nil, fmt.Errorf("please set proper probe value, the values can be either true or false") + } else { + sbPoolRunProbes, _ = strconv.ParseBool(probeValue) + } + } + + actOnProbeValue, ok := os.LookupEnv("ULTRADNS_ENABLE_ACTONPROBE") + if ok { + if (actOnProbeValue != "true") && (actOnProbeValue != "false") { + return nil, fmt.Errorf("please set proper act on probe value, the values can be either true or false") + } else { + sbPoolActOnProbes, _ = strconv.ParseBool(actOnProbeValue) + } + } + + poolValue, ok := os.LookupEnv("ULTRADNS_POOL_TYPE") + if ok { + if (poolValue != "sbpool") && (poolValue != "rdpool") { + return nil, fmt.Errorf(" please set proper ULTRADNS_POOL_TYPE, supported types are sbpool or rdpool") + } + ultradnsPoolType = poolValue + } + + client, err := udnssdk.NewClient(Username, string(Password), BaseURL) + if err != nil { + + return nil, fmt.Errorf("Connection cannot be established") + } + + provider := &UltraDNSProvider{ + client: *client, + domainFilter: domainFilter, + DryRun: dryRun, + AccountName: AccountName, + } + + return provider, nil +} + +// Zones returns list of hosted zones +func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { + zoneKey := &udnssdk.ZoneKey{} + if p.AccountName != "" { + zoneKey = &udnssdk.ZoneKey{ + Zone: "", + AccountName: p.AccountName, + } + } + + zones, err := p.fetchZones(ctx, zoneKey) + if err != nil { + return nil, err + } + + return zones, nil +} + +func (p *UltraDNSProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { + var endpoints []*endpoint.Endpoint + + zones, err := p.Zones(ctx) + if err != nil { + return nil, err + } + + for _, zone := range zones { + log.Infof("zones : %v", zone) + rrsetType := "" + ownerName := "" + rrsetKey := udnssdk.RRSetKey{ + Zone: zone.Properties.Name, + Type: rrsetType, + Name: ownerName, + } + + if zone.Properties.ResourceRecordCount != 0 { + records, err := p.fetchRecords(ctx, rrsetKey) + if err != nil { + return nil, err + } + + for _, r := range records { + recordTypeArray := strings.Fields(r.RRType) + if supportedRecordType(recordTypeArray[0]) { + log.Infof("owner name %s", r.OwnerName) + name := fmt.Sprintf("%s", r.OwnerName) + + // root name is identified by the empty string and should be + // translated to zone name for the endpoint entry. + if r.OwnerName == "" { + name = zone.Properties.Name + } + + endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL), r.RData...) + endpoints = append(endpoints, endPointTTL) + } + } + } + + } + log.Infof("endpoints %v", endpoints) + return endpoints, nil +} + +func (p *UltraDNSProvider) fetchRecords(ctx context.Context, k udnssdk.RRSetKey) ([]udnssdk.RRSet, error) { + // TODO: Sane Configuration for timeouts / retries + maxerrs := 5 + waittime := 5 * time.Second + + rrsets := []udnssdk.RRSet{} + errcnt := 0 + offset := 0 + limit := 1000 + + for { + reqRrsets, ri, res, err := p.client.RRSets.SelectWithOffsetWithLimit(k, offset, limit) + if err != nil { + if res != nil && res.StatusCode >= 500 { + errcnt = errcnt + 1 + if errcnt < maxerrs { + time.Sleep(waittime) + continue + } + } + return rrsets, err + } + + for _, rrset := range reqRrsets { + rrsets = append(rrsets, rrset) + } + if ri.ReturnedCount+ri.Offset >= ri.TotalCount { + return rrsets, nil + } + offset = ri.ReturnedCount + ri.Offset + continue + } +} + +func (p *UltraDNSProvider) fetchZones(ctx context.Context, zoneKey *udnssdk.ZoneKey) ([]udnssdk.Zone, error) { + // Select will list the zone rrsets, paginating through all available results + // TODO: Sane Configuration for timeouts / retries + maxerrs := 5 + waittime := 5 * time.Second + + zones := []udnssdk.Zone{} + + errcnt := 0 + offset := 0 + limit := 1000 + + for { + reqZones, ri, res, err := p.client.Zone.SelectWithOffsetWithLimit(zoneKey, offset, limit) + if err != nil { + if res != nil && res.StatusCode >= 500 { + errcnt = errcnt + 1 + if errcnt < maxerrs { + time.Sleep(waittime) + continue + } + } + return zones, err + } + + for _, zone := range reqZones { + + if p.domainFilter.IsConfigured() { + if p.domainFilter.Match(zone.Properties.Name) { + zones = append(zones, zone) + } + } else { + zones = append(zones, zone) + } + } + if ri.ReturnedCount+ri.Offset >= ri.TotalCount { + return zones, nil + } + offset = ri.ReturnedCount + ri.Offset + continue + } +} + +func (p *UltraDNSProvider) submitChanges(ctx context.Context, changes []*UltraDNSChanges) error { + cnameownerName := "cname" + txtownerName := "txt" + if len(changes) == 0 { + log.Infof("All records are already up to date") + return nil + } + + zones, err := p.Zones(ctx) + if err != nil { + return err + } + zoneChanges := seperateChangeByZone(zones, changes) + + for zoneName, changes := range zoneChanges { + + for _, change := range changes { + + if change.ResourceRecordSetUltraDNS.RRType == "CNAME" { + cnameownerName = change.ResourceRecordSetUltraDNS.OwnerName + } else if change.ResourceRecordSetUltraDNS.RRType == "TXT" { + txtownerName = change.ResourceRecordSetUltraDNS.OwnerName + } + + if cnameownerName == txtownerName { + rrsetKey := udnssdk.RRSetKey{ + Zone: zoneName, + Type: endpoint.RecordTypeCNAME, + Name: change.ResourceRecordSetUltraDNS.OwnerName, + } + err := p.getSpecificRecord(ctx, rrsetKey) + if err != nil { + return err + } + if p.DryRun != true { + _, err = p.client.RRSets.Delete(rrsetKey) + if err != nil { + return err + } + } + return fmt.Errorf("The CNAME and TXT Record name cannot be same please recreate external-dns with - --txt-prefix=") + } + rrsetKey := udnssdk.RRSetKey{ + Zone: zoneName, + Type: change.ResourceRecordSetUltraDNS.RRType, + Name: change.ResourceRecordSetUltraDNS.OwnerName, + } + record := udnssdk.RRSet{} + if ((change.ResourceRecordSetUltraDNS.RRType == "A" || change.ResourceRecordSetUltraDNS.RRType == "AAAA" ) && (len(change.ResourceRecordSetUltraDNS.RData) >= 2)) { + if ultradnsPoolType == "sbpool" && change.ResourceRecordSetUltraDNS.RRType == "A" { + sbPoolObject, _ := p.newSBPoolObjectCreation(ctx, change) + record = udnssdk.RRSet{ + RRType: change.ResourceRecordSetUltraDNS.RRType, + OwnerName: change.ResourceRecordSetUltraDNS.OwnerName, + RData: change.ResourceRecordSetUltraDNS.RData, + TTL: change.ResourceRecordSetUltraDNS.TTL, + Profile: sbPoolObject.RawProfile(), + } + } else if ultradnsPoolType == "rdpool" { + rdPoolObject, _ := p.newRDPoolObjectCreation(ctx, change) + record = udnssdk.RRSet{ + RRType: change.ResourceRecordSetUltraDNS.RRType, + OwnerName: change.ResourceRecordSetUltraDNS.OwnerName, + RData: change.ResourceRecordSetUltraDNS.RData, + TTL: change.ResourceRecordSetUltraDNS.TTL, + Profile: rdPoolObject.RawProfile(), + } + }else{ + return fmt.Errorf("We do not support Multiple target AAAA records in SB Pool please contact to Neustar for further details") + } + }else { + record = udnssdk.RRSet{ + RRType: change.ResourceRecordSetUltraDNS.RRType, + OwnerName: change.ResourceRecordSetUltraDNS.OwnerName, + RData: change.ResourceRecordSetUltraDNS.RData, + TTL: change.ResourceRecordSetUltraDNS.TTL, + } + } + + log.WithFields(log.Fields{ + "record": record.OwnerName, + "type": record.RRType, + "ttl": record.TTL, + "action": change.Action, + "zone": zoneName, + "profile": record.Profile, + }).Info("Changing record.") + + switch change.Action { + case ultradnsCreate: + if p.DryRun != true { + res, err := p.client.RRSets.Create(rrsetKey, record) + _ = res + if err != nil { + return err + } + } + + case ultradnsDelete: + err := p.getSpecificRecord(ctx, rrsetKey) + if err != nil { + return err + } + + if p.DryRun != true { + _, err = p.client.RRSets.Delete(rrsetKey) + if err != nil { + return err + } + } + case ultradnsUpdate: + err := p.getSpecificRecord(ctx, rrsetKey) + if err != nil { + return err + } + + if p.DryRun != true { + _, err = p.client.RRSets.Update(rrsetKey, record) + if err != nil { + return err + } + } + } + } + } + + return nil +} + +func (p *UltraDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { + combinedChanges := make([]*UltraDNSChanges, 0, len(changes.Create)+len(changes.UpdateNew)+len(changes.Delete)) + log.Infof("value of changes %v,%v,%v", changes.Create, changes.UpdateNew, changes.Delete) + combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsCreate, changes.Create)...) + combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsUpdate, changes.UpdateNew)...) + combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsDelete, changes.Delete)...) + + return p.submitChanges(ctx, combinedChanges) +} + +func newUltraDNSChanges(action string, endpoints []*endpoint.Endpoint) []*UltraDNSChanges { + changes := make([]*UltraDNSChanges, 0, len(endpoints)) + ttl := ultradnsDefaultTTL + for _, e := range endpoints { + + if e.RecordTTL.IsConfigured() { + ttl = int(e.RecordTTL) + } + + // Adding suffix dot to the record name + recordName := fmt.Sprintf("%s.", e.DNSName) + change := &UltraDNSChanges{ + Action: action, + ResourceRecordSetUltraDNS: udnssdk.RRSet{ + RRType: e.RecordType, + OwnerName: recordName, + RData: e.Targets, + TTL: ttl, + }, + } + changes = append(changes, change) + } + return changes +} + +func seperateChangeByZone(zones []udnssdk.Zone, changes []*UltraDNSChanges) map[string][]*UltraDNSChanges { + change := make(map[string][]*UltraDNSChanges) + zoneNameID := zoneIDName{} + for _, z := range zones { + zoneNameID.Add(z.Properties.Name, z.Properties.Name) + change[z.Properties.Name] = []*UltraDNSChanges{} + } + + for _, c := range changes { + zone, _ := zoneNameID.FindZone(c.ResourceRecordSetUltraDNS.OwnerName) + if zone == "" { + log.Infof("Skipping record %s because no hosted zone matching record DNS Name was detected", c.ResourceRecordSetUltraDNS.OwnerName) + continue + } + change[zone] = append(change[zone], c) + + } + return change +} + +func (p *UltraDNSProvider) getSpecificRecord(ctx context.Context, rrsetKey udnssdk.RRSetKey) (err error) { + _, err = p.client.RRSets.Select(rrsetKey) + if err != nil { + return fmt.Errorf("no record was found for %v", rrsetKey) + } else { + return nil + } +} + +// Creation of SBPoolObject +func (p *UltraDNSProvider) newSBPoolObjectCreation(ctx context.Context, change *UltraDNSChanges) (sbPool udnssdk.SBPoolProfile, err error) { + + sbpoolRDataList := []udnssdk.SBRDataInfo{} + for _, _ = range change.ResourceRecordSetUltraDNS.RData { + + rrdataInfo := udnssdk.SBRDataInfo{ + RunProbes: sbPoolRunProbes, + Priority: sbPoolPriority, + State: "NORMAL", + Threshold: 1, + Weight: nil, + } + sbpoolRDataList = append(sbpoolRDataList, rrdataInfo) + } + sbPoolObject := udnssdk.SBPoolProfile{ + Context: udnssdk.SBPoolSchema, + Order: sbPoolOrder, + Description: change.ResourceRecordSetUltraDNS.OwnerName, + MaxActive: len(change.ResourceRecordSetUltraDNS.RData), + MaxServed: len(change.ResourceRecordSetUltraDNS.RData), + RDataInfo: sbpoolRDataList, + RunProbes: sbPoolRunProbes, + ActOnProbes: sbPoolActOnProbes, + } + return sbPoolObject, nil +} + +//Creation of RDPoolObject +func (p *UltraDNSProvider) newRDPoolObjectCreation(ctx context.Context, change *UltraDNSChanges) (rdPool udnssdk.RDPoolProfile, err error) { + + rdPoolObject := udnssdk.RDPoolProfile{ + Context: udnssdk.RDPoolSchema, + Order: rdPoolOrder, + Description: change.ResourceRecordSetUltraDNS.OwnerName, + } + return rdPoolObject, nil +} diff --git a/provider/ultradns_test.go b/provider/ultradns_test.go new file mode 100644 index 000000000..445e87432 --- /dev/null +++ b/provider/ultradns_test.go @@ -0,0 +1,686 @@ +/* +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 provider + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/http" + "os" + "reflect" + _ "strings" + "testing" + + udnssdk "github.com/ultradns/ultradns-sdk-go" + "github.com/stretchr/testify/assert" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/external-dns/plan" +) + +type mockUltraDNSZone struct { + client *udnssdk.Client +} + +func (m *mockUltraDNSZone) SelectWithOffsetWithLimit(k *udnssdk.ZoneKey, offset int, limit int) (zones []udnssdk.Zone, ResultInfo udnssdk.ResultInfo, resp *http.Response, err error) { + zones = []udnssdk.Zone{} + zone := udnssdk.Zone{} + zoneJson := ` + { + "properties": { + "name":"test-ultradns-provider.com.", + "accountName":"teamrest", + "type":"PRIMARY", + "dnssecStatus":"UNSIGNED", + "status":"ACTIVE", + "owner":"teamrest", + "resourceRecordCount":7, + "lastModifiedDateTime":"" + } + }` + if err := json.Unmarshal([]byte(zoneJson), &zone); err != nil { + log.Fatal(err) + } + + zones = append(zones, zone) + return zones, udnssdk.ResultInfo{}, nil, nil +} + +type mockUltraDNSRecord struct { + client *udnssdk.Client +} + +func (m *mockUltraDNSRecord) Create(k udnssdk.RRSetKey, rrset udnssdk.RRSet) (*http.Response, error) { + return nil, nil +} + +func (m *mockUltraDNSRecord) Select(k udnssdk.RRSetKey) ([]udnssdk.RRSet, error) { + return []udnssdk.RRSet{{ + OwnerName: "test-ultradns-provider.com.", + RRType: endpoint.RecordTypeA, + RData: []string{"1.1.1.1"}, + TTL: 86400, + }}, nil + +} + +func (m *mockUltraDNSRecord) SelectWithOffset(k udnssdk.RRSetKey, offset int) ([]udnssdk.RRSet, udnssdk.ResultInfo, *http.Response, error) { + return nil, udnssdk.ResultInfo{}, nil, nil +} + +func (m *mockUltraDNSRecord) Update(udnssdk.RRSetKey, udnssdk.RRSet) (*http.Response, error) { + return nil, nil +} + +func (m *mockUltraDNSRecord) Delete(k udnssdk.RRSetKey) (*http.Response, error) { + return nil, nil +} + +func (m *mockUltraDNSRecord) SelectWithOffsetWithLimit(k udnssdk.RRSetKey, offset int, limit int) (rrsets []udnssdk.RRSet, ResultInfo udnssdk.ResultInfo, resp *http.Response, err error) { + return []udnssdk.RRSet{{ + OwnerName: "test-ultradns-provider.com.", + RRType: endpoint.RecordTypeA, + RData: []string{"1.1.1.1"}, + TTL: 86400, + }}, udnssdk.ResultInfo{}, nil, nil +} + +// NewUltraDNSProvider Test scenario +func TestNewUltraDNSProvider(t *testing.T) { + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.Nil(t,err) + + _ = os.Unsetenv("ULTRADNS_PASSWORD") + _ = os.Unsetenv("ULTRADNS_USERNAME") + _ = os.Unsetenv("ULTRADNS_BASEURL") + _ = os.Unsetenv("ULTRADNS_ACCOUNTNAME") + _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Expected to fail %s","formatted") +} + +//zones function test scenario +func TestUltraDNSProvider_Zones(t *testing.T) { + mocked := mockUltraDNSZone{} + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + Zone: &mocked, + }, + } + + zoneKey := &udnssdk.ZoneKey{ + Zone: "", + AccountName: "teamrest", + } + + expected, _, _, err := provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) + assert.Nil(t,err) + zones, err := provider.Zones(context.Background()) + assert.Nil(t,err) + assert.Equal(t,reflect.DeepEqual(expected, zones),true) +} + +//Records function test case +func TestUltraDNSProvider_Records(t *testing.T) { + mocked := mockUltraDNSRecord{} + mockedDomain := mockUltraDNSZone{} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + rrsetKey := udnssdk.RRSetKey{} + expected, _, _, err := provider.client.RRSets.SelectWithOffsetWithLimit(rrsetKey, 0, 1000) + records, err := provider.Records(context.Background()) + assert.Nil(t,err) + for _, v := range records { + assert.Equal(t, fmt.Sprintf("%s.", v.DNSName), expected[0].OwnerName) + assert.Equal(t, v.RecordType, expected[0].RRType) + assert.Equal(t, int(v.RecordTTL), expected[0].TTL) + } + +} + +//ApplyChanges function testcase +func TestUltraDNSProvider_ApplyChanges(t *testing.T) { + changes := &plan.Changes{} + mocked := mockUltraDNSRecord{nil} + mockedDomain := mockUltraDNSZone{nil} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + + changes.Create = []*endpoint.Endpoint{ + {DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A"}, + {DNSName: "ttl.test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", RecordTTL: 100}, + } + changes.Create = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.2"}, RecordType: "A"}} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2", "1.1.2.3", "1.1.2.4"}, RecordType: "A", RecordTTL: 100}} + changes.Delete = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2", "1.1.2.3", "1.1.2.4"}, RecordType: "A", RecordTTL: 100}} + changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", RecordTTL: 100}} + err := provider.ApplyChanges(context.Background(), changes) + assert.Nilf(t,err,"Should not fail %s","formatted") +} + +// Testing function getSpecificRecord +func TestUltraDNSProvider_getSpecificRecord(t *testing.T) { + mocked := mockUltraDNSRecord{nil} + mockedDomain := mockUltraDNSZone{nil} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + + recordSetKey := udnssdk.RRSetKey{ + Zone: "test-ultradns-provider.com.", + Type: "A", + Name: "teamrest", + } + err := provider.getSpecificRecord(context.Background(), recordSetKey) + assert.Nil(t,err) +} + +//Fail case scenario testing where CNAME and TXT Record name are same +func TestUltraDNSProvider_ApplyChangesCNAME(t *testing.T) { + changes := &plan.Changes{} + mocked := mockUltraDNSRecord{nil} + mockedDomain := mockUltraDNSZone{nil} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + + changes.Create = []*endpoint.Endpoint{ + {DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "CNAME"}, + {DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "TXT"}, + } + + err := provider.ApplyChanges(context.Background(), changes) + assert.NotNil(t,err) +} + +// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be avaialble "kubernetes-ultradns-provider-test.com" +func TestUltraDNSProvider_ApplyChanges_Integration(t *testing.T) { + + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + + providerUltradns, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{ + {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A"}, + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, RecordType: "AAAA", RecordTTL: 100}, + } + + err = providerUltradns.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + + rrsetKey := udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "kubernetes-ultradns-provider-test.com.", + Type: "A", + } + + rrsets, _ := providerUltradns.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData[0], "1.1.1.1") + + rrsetKey = udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "ttl.kubernetes-ultradns-provider-test.com.", + Type: "AAAA", + } + + rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData[0], "2001:db8:85a3:0:0:8a2e:370:7334") + + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{ + {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}, + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}} + err = providerUltradns.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + + rrsetKey = udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "kubernetes-ultradns-provider-test.com.", + Type: "A", + } + + rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData[0], "1.1.2.2") + + rrsetKey = udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "ttl.kubernetes-ultradns-provider-test.com.", + Type: "AAAA", + } + + rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData[0], "2001:db8:85a3:0:0:8a2e:370:7335") + + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{ + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}, + {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}} + + err = providerUltradns.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + + resp, _ := providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + + resp, _ = providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + + } + +} + +// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be avaialble "kubernetes-ultradns-provider-test.com" for multiple target +func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) { + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + + provider, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{ + {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.1.2.2"}, RecordType: "A"}} + + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + + rrsetKey := udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "kubernetes-ultradns-provider-test.com.", + Type: "A", + } + + rrsets, _ := provider.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData, []string{"1.1.1.1", "1.1.2.2"}) + + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}} + + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + + rrsetKey = udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "kubernetes-ultradns-provider-test.com.", + Type: "A", + } + + rrsets, _ = provider.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData, []string{"1.1.2.2", "192.168.0.24", "1.2.3.4"}) + + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}} + + err = provider.ApplyChanges(context.Background(), changes) + + assert.Nil(t,err) + + rrsetKey = udnssdk.RRSetKey{ + Zone: "kubernetes-ultradns-provider-test.com.", + Name: "kubernetes-ultradns-provider-test.com.", + Type: "A", + } + + rrsets, _ = provider.client.RRSets.Select(rrsetKey) + assert.Equal(t, rrsets[0].RData, []string{"1.1.2.2"}) + + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A"}} + + err = provider.ApplyChanges(context.Background(), changes) + + assert.Nil(t,err) + + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + + } +} + +// Test case to check sbpool creation +func TestUltraDNSProvider_newSBPoolObjectCreation(t *testing.T) { + mocked := mockUltraDNSRecord{nil} + mockedDomain := mockUltraDNSZone{nil} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + sbpoolRDataList := []udnssdk.SBRDataInfo{} + changes := &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com.", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A", RecordTTL: 100}} + changesList := &UltraDNSChanges{ + Action: "UPDATE", + ResourceRecordSetUltraDNS: udnssdk.RRSet{ + RRType: "A", + OwnerName: "kubernetes-ultradns-provider-test.com.", + RData: []string{"1.1.2.2", "192.168.0.24"}, + TTL: 100, + }, + } + + for _, _ = range changesList.ResourceRecordSetUltraDNS.RData { + + rrdataInfo := udnssdk.SBRDataInfo{ + RunProbes: true, + Priority: 1, + State: "NORMAL", + Threshold: 1, + Weight: nil, + } + sbpoolRDataList = append(sbpoolRDataList, rrdataInfo) + } + sbPoolObject := udnssdk.SBPoolProfile{ + Context: udnssdk.SBPoolSchema, + Order: "ROUND_ROBIN", + Description: "kubernetes-ultradns-provider-test.com.", + MaxActive: 2, + MaxServed: 2, + RDataInfo: sbpoolRDataList, + RunProbes: true, + ActOnProbes: true, + } + + actualSBPoolObject, _ := provider.newSBPoolObjectCreation(context.Background(), changesList) + assert.Equal(t, sbPoolObject, actualSBPoolObject) + +} + +//Testcase to check fail scenario for multiple AAAA targets +func TestUltraDNSProvider_MultipleTargetAAAA(t *testing.T) { + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") + + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{ + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}, + } + err := provider.ApplyChanges(context.Background(), changes) + assert.NotNilf(t,err,"We wanted it to fail since multiple AAAA targets are not allowed %s","formatted") + + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + _ = os.Unsetenv("ULTRADNS_POOL_TYPE") + } +} + +//Testcase to check fail scenario for multiple AAAA targets +func TestUltraDNSProvider_MultipleTargetAAAARDPool(t *testing.T) { + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + _ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool") + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{ + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}, + } + err := provider.ApplyChanges(context.Background(), changes) + assert.Nilf(t,err," multiple AAAA targets are allowed when pool is RDPool %s","formatted") + + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") + + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA"}} + + err = provider.ApplyChanges(context.Background(), changes) + + assert.Nil(t,err) + + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + + } +} + +// Test case to check multiple CNAME targets. +func TestUltraDNSProvider_MultipleTargetCNAME(t *testing.T) { + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + provider, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + + changes.Create = []*endpoint.Endpoint{ + {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"nginx.loadbalancer.com.", "nginx1.loadbalancer.com."}, RecordType: "CNAME", RecordTTL: 100}, + } + err = provider.ApplyChanges(context.Background(), changes) + + assert.NotNilf(t,err,"We wanted it to fail since multiple CNAME targets are not allowed %s","formatted") + + + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/CNAME/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + } +} + +//Testing creation of RD Pool +func TestUltraDNSProvider_newRDPoolObjectCreation(t *testing.T) { + mocked := mockUltraDNSRecord{nil} + mockedDomain := mockUltraDNSZone{nil} + + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + RRSets: &mocked, + Zone: &mockedDomain, + }, + } + changes := &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com.", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A", RecordTTL: 100}} + changesList := &UltraDNSChanges{ + Action: "UPDATE", + ResourceRecordSetUltraDNS: udnssdk.RRSet{ + RRType: "A", + OwnerName: "kubernetes-ultradns-provider-test.com.", + RData: []string{"1.1.2.2", "192.168.0.24"}, + TTL: 100, + }, + } + rdPoolObject := udnssdk.RDPoolProfile{ + Context: udnssdk.RDPoolSchema, + Order: "ROUND_ROBIN", + Description: "kubernetes-ultradns-provider-test.com.", + } + + actualRDPoolObject, _ := provider.newRDPoolObjectCreation(context.Background(), changesList) + assert.Equal(t, rdPoolObject, actualRDPoolObject) + +} + +//Testing Failure scenarios over NewUltraDNS Provider +func TestNewUltraDNSProvider_FailCases(t *testing.T) { + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_POOL_TYPE", "xyz") + _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Pool Type other than given type not working %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_ENABLE_PROBING", "adefg") + _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Probe value other than given values not working %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "adefg") + _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"ActOnProbe value other than given values not working %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Unsetenv("ULTRADNS_PASSWORD") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Expected to give error if password is not set %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Unsetenv("ULTRADNS_BASEURL") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Expected to give error if baseurl is not set %s","formatted") + + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Unsetenv("ULTRADNS_ACCOUNTNAME") + _ = os.Unsetenv("ULTRADNS_ENABLE_ACTONPROBE") + _ = os.Unsetenv("ULTRADNS_ENABLE_PROBING") + _ = os.Unsetenv("ULTRADNS_POOL_TYPE") + _, accounterr := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.Nil(t,accounterr) + +} + +// Testing success scenarios for newly introduced environment variables +func TestNewUltraDNSProvider_NewEnvVariableSuccessCases(t *testing.T) { + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_POOL_TYPE", "rdpool") + _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.Nilf(t,err,"Pool Type not working in proper scenario %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_ENABLE_PROBING", "false") + _, err1 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.Nilf(t,err1,"Probe given value is not working %s","formatted") + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true") + _, err2 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.Nilf(t,err2,"ActOnProbe given value is not working %s","formatted") + + +} + +// Base64 Bad string decoding scenario +func TestNewUltraDNSProvider_Base64DecodeFailcase(t *testing.T) { + + _ = os.Setenv("ULTRADNS_USERNAME", "") + _ = os.Setenv("ULTRADNS_PASSWORD", "12345") + _ = os.Setenv("ULTRADNS_BASEURL", "") + _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") + _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true") + _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) + assert.NotNilf(t,err,"Base64 decode should fail in this case %s","formatted") + +} + +func TestUltraDNSProvider_PoolConversionCase(t *testing.T){ + + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + //Creating SBPool Record + _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}} + err := provider.ApplyChanges(context.Background(), changes) + assert.Nilf(t,err," multiple A record creation with SBPool %s","formatted") + + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") + + //Coverting to RD Pool + _ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool") + provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.5"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") + + + //Coverting back to SB Pool + _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") + provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") + + //Deleting Record + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t,err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + } +} From 00ecf547e6d6ea53e247bf2f3e2988fef64baab6 Mon Sep 17 00:00:00 2001 From: kbhandari Date: Mon, 15 Jun 2020 19:16:10 +0000 Subject: [PATCH 3/8] Quick fixed ultradns.md doc --- docs/tutorials/ultradns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md index 86d39d9ef..98b4a9793 100644 --- a/docs/tutorials/ultradns.md +++ b/docs/tutorials/ultradns.md @@ -612,7 +612,7 @@ $ kubectl create -f apple-banana-echo.yaml $ kubectl create -f external-dns.yaml ``` - Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service. --o Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com". +- Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com". - Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone "example.com": ```console $ kubectl delete -f apple-banana-echo.yaml From 667a20aa7170abe631deffe5115394677f200edc Mon Sep 17 00:00:00 2001 From: kbhandari Date: Mon, 15 Jun 2020 21:51:10 +0000 Subject: [PATCH 4/8] Added Domain filter scenario --- provider/ultradns.go | 78 ++++++++++----- provider/ultradns_test.go | 195 ++++++++++++++++++++++---------------- 2 files changed, 166 insertions(+), 107 deletions(-) diff --git a/provider/ultradns.go b/provider/ultradns.go index fb1846ebb..b83cc22b6 100644 --- a/provider/ultradns.go +++ b/provider/ultradns.go @@ -22,7 +22,7 @@ import ( "strings" "time" - udnssdk "github.com/ultradns/ultradns-sdk-go" + udnssdk "github.com/aliasgharmhowwala/ultradns-sdk-go" log "github.com/sirupsen/logrus" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" @@ -45,7 +45,7 @@ var ultradnsPoolType = "rdpool" //Setting custom headers for ultradns api calls var customHeader = []udnssdk.CustomHeader{ - udnssdk.CustomHeader { + udnssdk.CustomHeader{ Key: "UltraClient", Value: "kube-client", }, @@ -139,19 +139,55 @@ func NewUltraDNSProvider(domainFilter endpoint.DomainFilter, dryRun bool) (*Ultr // Zones returns list of hosted zones func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { zoneKey := &udnssdk.ZoneKey{} - if p.AccountName != "" { - zoneKey = &udnssdk.ZoneKey{ - Zone: "", - AccountName: p.AccountName, + zones_appender := []udnssdk.Zone{} + if p.domainFilter.IsConfigured() { + + for _, zone := range p.domainFilter.Filters { + if p.AccountName != "" { + zoneKey = &udnssdk.ZoneKey{ + Zone: zone, + AccountName: p.AccountName, + } + + zones, err := p.fetchZones(ctx, zoneKey) + if err != nil { + return nil, err + } + + zones_appender = append(zones_appender, zones...) + + } else { + + zoneKey = &udnssdk.ZoneKey{ + Zone: zone, + } + + zones, err := p.fetchZones(ctx, zoneKey) + if err != nil { + return nil, err + } + + zones_appender = append(zones_appender, zones...) + } } - } - zones, err := p.fetchZones(ctx, zoneKey) - if err != nil { - return nil, err - } + return zones_appender, nil - return zones, nil + } else { + if p.AccountName != "" { + zoneKey = &udnssdk.ZoneKey{ + Zone: "", + AccountName: p.AccountName, + } + } + + zones, err := p.fetchZones(ctx, zoneKey) + if err != nil { + return nil, err + } + + return zones, nil + } } func (p *UltraDNSProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { @@ -238,14 +274,14 @@ func (p *UltraDNSProvider) fetchRecords(ctx context.Context, k udnssdk.RRSetKey) func (p *UltraDNSProvider) fetchZones(ctx context.Context, zoneKey *udnssdk.ZoneKey) ([]udnssdk.Zone, error) { // Select will list the zone rrsets, paginating through all available results // TODO: Sane Configuration for timeouts / retries + offset := 0 + limit := 1000 maxerrs := 5 waittime := 5 * time.Second zones := []udnssdk.Zone{} errcnt := 0 - offset := 0 - limit := 1000 for { reqZones, ri, res, err := p.client.Zone.SelectWithOffsetWithLimit(zoneKey, offset, limit) @@ -262,13 +298,7 @@ func (p *UltraDNSProvider) fetchZones(ctx context.Context, zoneKey *udnssdk.Zone for _, zone := range reqZones { - if p.domainFilter.IsConfigured() { - if p.domainFilter.Match(zone.Properties.Name) { - zones = append(zones, zone) - } - } else { - zones = append(zones, zone) - } + zones = append(zones, zone) } if ri.ReturnedCount+ri.Offset >= ri.TotalCount { return zones, nil @@ -326,7 +356,7 @@ func (p *UltraDNSProvider) submitChanges(ctx context.Context, changes []*UltraDN Name: change.ResourceRecordSetUltraDNS.OwnerName, } record := udnssdk.RRSet{} - if ((change.ResourceRecordSetUltraDNS.RRType == "A" || change.ResourceRecordSetUltraDNS.RRType == "AAAA" ) && (len(change.ResourceRecordSetUltraDNS.RData) >= 2)) { + if (change.ResourceRecordSetUltraDNS.RRType == "A" || change.ResourceRecordSetUltraDNS.RRType == "AAAA") && (len(change.ResourceRecordSetUltraDNS.RData) >= 2) { if ultradnsPoolType == "sbpool" && change.ResourceRecordSetUltraDNS.RRType == "A" { sbPoolObject, _ := p.newSBPoolObjectCreation(ctx, change) record = udnssdk.RRSet{ @@ -345,10 +375,10 @@ func (p *UltraDNSProvider) submitChanges(ctx context.Context, changes []*UltraDN TTL: change.ResourceRecordSetUltraDNS.TTL, Profile: rdPoolObject.RawProfile(), } - }else{ + } else { return fmt.Errorf("We do not support Multiple target AAAA records in SB Pool please contact to Neustar for further details") } - }else { + } else { record = udnssdk.RRSet{ RRType: change.ResourceRecordSetUltraDNS.RRType, OwnerName: change.ResourceRecordSetUltraDNS.OwnerName, diff --git a/provider/ultradns_test.go b/provider/ultradns_test.go index 445e87432..9b410ecbe 100644 --- a/provider/ultradns_test.go +++ b/provider/ultradns_test.go @@ -27,7 +27,7 @@ import ( _ "strings" "testing" - udnssdk "github.com/ultradns/ultradns-sdk-go" + udnssdk "github.com/aliasgharmhowwala/ultradns-sdk-go" "github.com/stretchr/testify/assert" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" @@ -107,14 +107,14 @@ func TestNewUltraDNSProvider(t *testing.T) { _ = os.Setenv("ULTRADNS_BASEURL", "") _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.Nil(t,err) + assert.Nil(t, err) _ = os.Unsetenv("ULTRADNS_PASSWORD") _ = os.Unsetenv("ULTRADNS_USERNAME") _ = os.Unsetenv("ULTRADNS_BASEURL") _ = os.Unsetenv("ULTRADNS_ACCOUNTNAME") _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Expected to fail %s","formatted") + assert.NotNilf(t, err, "Expected to fail %s", "formatted") } //zones function test scenario @@ -132,10 +132,10 @@ func TestUltraDNSProvider_Zones(t *testing.T) { } expected, _, _, err := provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) - assert.Nil(t,err) + assert.Nil(t, err) zones, err := provider.Zones(context.Background()) - assert.Nil(t,err) - assert.Equal(t,reflect.DeepEqual(expected, zones),true) + assert.Nil(t, err) + assert.Equal(t, reflect.DeepEqual(expected, zones), true) } //Records function test case @@ -152,7 +152,7 @@ func TestUltraDNSProvider_Records(t *testing.T) { rrsetKey := udnssdk.RRSetKey{} expected, _, _, err := provider.client.RRSets.SelectWithOffsetWithLimit(rrsetKey, 0, 1000) records, err := provider.Records(context.Background()) - assert.Nil(t,err) + assert.Nil(t, err) for _, v := range records { assert.Equal(t, fmt.Sprintf("%s.", v.DNSName), expected[0].OwnerName) assert.Equal(t, v.RecordType, expected[0].RRType) @@ -184,7 +184,7 @@ func TestUltraDNSProvider_ApplyChanges(t *testing.T) { changes.Delete = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2", "1.1.2.3", "1.1.2.4"}, RecordType: "A", RecordTTL: 100}} changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", RecordTTL: 100}} err := provider.ApplyChanges(context.Background(), changes) - assert.Nilf(t,err,"Should not fail %s","formatted") + assert.Nilf(t, err, "Should not fail %s", "formatted") } // Testing function getSpecificRecord @@ -205,7 +205,7 @@ func TestUltraDNSProvider_getSpecificRecord(t *testing.T) { Name: "teamrest", } err := provider.getSpecificRecord(context.Background(), recordSetKey) - assert.Nil(t,err) + assert.Nil(t, err) } //Fail case scenario testing where CNAME and TXT Record name are same @@ -227,7 +227,7 @@ func TestUltraDNSProvider_ApplyChangesCNAME(t *testing.T) { } err := provider.ApplyChanges(context.Background(), changes) - assert.NotNil(t,err) + assert.NotNil(t, err) } // This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be avaialble "kubernetes-ultradns-provider-test.com" @@ -247,7 +247,7 @@ func TestUltraDNSProvider_ApplyChanges_Integration(t *testing.T) { } err = providerUltradns.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) rrsetKey := udnssdk.RRSetKey{ Zone: "kubernetes-ultradns-provider-test.com.", @@ -272,7 +272,7 @@ func TestUltraDNSProvider_ApplyChanges_Integration(t *testing.T) { {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}, {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}} err = providerUltradns.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) rrsetKey = udnssdk.RRSetKey{ Zone: "kubernetes-ultradns-provider-test.com.", @@ -298,7 +298,7 @@ func TestUltraDNSProvider_ApplyChanges_Integration(t *testing.T) { {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}} err = providerUltradns.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) resp, _ := providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) assert.Equal(t, resp.Status, "404 Not Found") @@ -324,7 +324,7 @@ func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) {DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.1.2.2"}, RecordType: "A"}} err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) rrsetKey := udnssdk.RRSetKey{ Zone: "kubernetes-ultradns-provider-test.com.", @@ -339,7 +339,7 @@ func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}} err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) rrsetKey = udnssdk.RRSetKey{ Zone: "kubernetes-ultradns-provider-test.com.", @@ -355,7 +355,7 @@ func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) rrsetKey = udnssdk.RRSetKey{ Zone: "kubernetes-ultradns-provider-test.com.", @@ -371,7 +371,7 @@ func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) + assert.Nil(t, err) resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) assert.Equal(t, resp.Status, "404 Not Found") @@ -437,7 +437,7 @@ func TestUltraDNSProvider_MultipleTargetAAAA(t *testing.T) { log.Printf("Skipping test") } else { - _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") + _ = os.Setenv("ULTRADNS_POOL_TYPE", "sbpool") provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) changes := &plan.Changes{} @@ -445,7 +445,7 @@ func TestUltraDNSProvider_MultipleTargetAAAA(t *testing.T) { {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}, } err := provider.ApplyChanges(context.Background(), changes) - assert.NotNilf(t,err,"We wanted it to fail since multiple AAAA targets are not allowed %s","formatted") + assert.NotNilf(t, err, "We wanted it to fail since multiple AAAA targets are not allowed %s", "formatted") resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) assert.Equal(t, resp.Status, "404 Not Found") @@ -460,29 +460,29 @@ func TestUltraDNSProvider_MultipleTargetAAAARDPool(t *testing.T) { log.Printf("Skipping test") } else { - _ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool") + _ = os.Setenv("ULTRADNS_POOL_TYPE", "rdpool") provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) changes := &plan.Changes{} changes.Create = []*endpoint.Endpoint{ {DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}, } err := provider.ApplyChanges(context.Background(), changes) - assert.Nilf(t,err," multiple AAAA targets are allowed when pool is RDPool %s","formatted") + assert.Nilf(t, err, " multiple AAAA targets are allowed when pool is RDPool %s", "formatted") resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) assert.Equal(t, resp.Status, "200 OK") - - changes = &plan.Changes{} - changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA"}} - err = provider.ApplyChanges(context.Background(), changes) + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA"}} - assert.Nil(t,err) + err = provider.ApplyChanges(context.Background(), changes) - resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, resp.Status, "404 Not Found") + assert.Nil(t, err) - } + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + + } } // Test case to check multiple CNAME targets. @@ -500,8 +500,7 @@ func TestUltraDNSProvider_MultipleTargetCNAME(t *testing.T) { } err = provider.ApplyChanges(context.Background(), changes) - assert.NotNilf(t,err,"We wanted it to fail since multiple CNAME targets are not allowed %s","formatted") - + assert.NotNilf(t, err, "We wanted it to fail since multiple CNAME targets are not allowed %s", "formatted") resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/CNAME/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) assert.Equal(t, resp.Status, "404 Not Found") @@ -549,7 +548,7 @@ func TestNewUltraDNSProvider_FailCases(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_POOL_TYPE", "xyz") _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Pool Type other than given type not working %s","formatted") + assert.NotNilf(t, err, "Pool Type other than given type not working %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_PASSWORD", "") @@ -557,7 +556,7 @@ func TestNewUltraDNSProvider_FailCases(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_ENABLE_PROBING", "adefg") _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Probe value other than given values not working %s","formatted") + assert.NotNilf(t, err, "Probe value other than given values not working %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_PASSWORD", "") @@ -565,22 +564,21 @@ func TestNewUltraDNSProvider_FailCases(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "adefg") _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"ActOnProbe value other than given values not working %s","formatted") + assert.NotNilf(t, err, "ActOnProbe value other than given values not working %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_BASEURL", "") _ = os.Unsetenv("ULTRADNS_PASSWORD") _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Expected to give error if password is not set %s","formatted") + assert.NotNilf(t, err, "Expected to give error if password is not set %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_PASSWORD", "") _ = os.Unsetenv("ULTRADNS_BASEURL") _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Expected to give error if baseurl is not set %s","formatted") - + assert.NotNilf(t, err, "Expected to give error if baseurl is not set %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_BASEURL", "") @@ -590,7 +588,7 @@ func TestNewUltraDNSProvider_FailCases(t *testing.T) { _ = os.Unsetenv("ULTRADNS_ENABLE_PROBING") _ = os.Unsetenv("ULTRADNS_POOL_TYPE") _, accounterr := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.Nil(t,accounterr) + assert.Nil(t, accounterr) } @@ -602,7 +600,7 @@ func TestNewUltraDNSProvider_NewEnvVariableSuccessCases(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_POOL_TYPE", "rdpool") _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.Nilf(t,err,"Pool Type not working in proper scenario %s","formatted") + assert.Nilf(t, err, "Pool Type not working in proper scenario %s", "formatted") _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_PASSWORD", "") @@ -610,17 +608,16 @@ func TestNewUltraDNSProvider_NewEnvVariableSuccessCases(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_ENABLE_PROBING", "false") _, err1 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.Nilf(t,err1,"Probe given value is not working %s","formatted") - + assert.Nilf(t, err1, "Probe given value is not working %s", "formatted") + _ = os.Setenv("ULTRADNS_USERNAME", "") _ = os.Setenv("ULTRADNS_PASSWORD", "") _ = os.Setenv("ULTRADNS_BASEURL", "") _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true") _, err2 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.Nilf(t,err2,"ActOnProbe given value is not working %s","formatted") + assert.Nilf(t, err2, "ActOnProbe given value is not working %s", "formatted") - } // Base64 Bad string decoding scenario @@ -632,55 +629,87 @@ func TestNewUltraDNSProvider_Base64DecodeFailcase(t *testing.T) { _ = os.Setenv("ULTRADNS_ACCOUNTNAME", "") _ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true") _, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true) - assert.NotNilf(t,err,"Base64 decode should fail in this case %s","formatted") + assert.NotNilf(t, err, "Base64 decode should fail in this case %s", "formatted") } -func TestUltraDNSProvider_PoolConversionCase(t *testing.T){ +func TestUltraDNSProvider_PoolConversionCase(t *testing.T) { - _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") - if !ok { - log.Printf("Skipping test") + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") - } else { + } else { //Creating SBPool Record - _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") - provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) - changes := &plan.Changes{} - changes.Create = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}} - err := provider.ApplyChanges(context.Background(), changes) - assert.Nilf(t,err," multiple A record creation with SBPool %s","formatted") + _ = os.Setenv("ULTRADNS_POOL_TYPE", "sbpool") + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes := &plan.Changes{} + changes.Create = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}} + err := provider.ApplyChanges(context.Background(), changes) + assert.Nilf(t, err, " multiple A record creation with SBPool %s", "formatted") - resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, resp.Status, "200 OK") - - //Coverting to RD Pool - _ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool") + resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") + + //Coverting to RD Pool + _ = os.Setenv("ULTRADNS_POOL_TYPE", "rdpool") provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) - changes = &plan.Changes{} - changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.5"}, RecordType: "A"}} - err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) - resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, resp.Status, "200 OK") - + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.5"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t, err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") - //Coverting back to SB Pool - _ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool") - provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) - changes = &plan.Changes{} - changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}} - err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) - resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, resp.Status, "200 OK") + //Coverting back to SB Pool + _ = os.Setenv("ULTRADNS_POOL_TYPE", "sbpool") + provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false) + changes = &plan.Changes{} + changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t, err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "200 OK") //Deleting Record - changes = &plan.Changes{} - changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}} - err = provider.ApplyChanges(context.Background(), changes) - assert.Nil(t,err) - resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, resp.Status, "404 Not Found") - } + changes = &plan.Changes{} + changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A"}} + err = provider.ApplyChanges(context.Background(), changes) + assert.Nil(t, err) + resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) + assert.Equal(t, resp.Status, "404 Not Found") + } +} + +func TestUltraDNSProvider_DomainFilter(t *testing.T) { + + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com", "kubernetes-ultradns-provider-test.com"}), true) + zones, err := provider.Zones(context.Background()) + assert.Equal(t, zones[0].Properties.Name, "kubernetes-ultradns-provider-test.com.") + assert.Equal(t, zones[1].Properties.Name, "kubernetes-ultradns-provider-test.com.") + assert.Nilf(t, err, " Multiple domain filter failed %s", "formatted") + + provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{}), true) + zones, err = provider.Zones(context.Background()) + assert.Nilf(t, err, " Multiple domain filter failed %s", "formatted") + + } +} + +func TestUltraDNSProvider_DomainFiltersZonesFailCase(t *testing.T) { + + _, ok := os.LookupEnv("ULTRADNS_INTEGRATION") + if !ok { + log.Printf("Skipping test") + + } else { + provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com", "kubernetes-uldsvdsvadvvdsvadvstradns-provider-test.com"}), true) + _, err := provider.Zones(context.Background()) + assert.NotNilf(t, err, " Multiple domain filter failed %s", "formatted") + } } From 784e9042b63679566e48c06024275939f286ce1d Mon Sep 17 00:00:00 2001 From: kbhandari Date: Tue, 16 Jun 2020 07:05:33 +0000 Subject: [PATCH 5/8] Added Domain filter test cases --- provider/ultradns.go | 2 +- provider/ultradns_test.go | 65 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/provider/ultradns.go b/provider/ultradns.go index b83cc22b6..84ef2dc06 100644 --- a/provider/ultradns.go +++ b/provider/ultradns.go @@ -22,8 +22,8 @@ import ( "strings" "time" - udnssdk "github.com/aliasgharmhowwala/ultradns-sdk-go" log "github.com/sirupsen/logrus" + udnssdk "github.com/ultradns/ultradns-sdk-go" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" ) diff --git a/provider/ultradns_test.go b/provider/ultradns_test.go index 9b410ecbe..8acab3579 100644 --- a/provider/ultradns_test.go +++ b/provider/ultradns_test.go @@ -27,8 +27,8 @@ import ( _ "strings" "testing" - udnssdk "github.com/aliasgharmhowwala/ultradns-sdk-go" "github.com/stretchr/testify/assert" + udnssdk "github.com/ultradns/ultradns-sdk-go" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" ) @@ -136,6 +136,7 @@ func TestUltraDNSProvider_Zones(t *testing.T) { zones, err := provider.Zones(context.Background()) assert.Nil(t, err) assert.Equal(t, reflect.DeepEqual(expected, zones), true) + } //Records function test case @@ -713,3 +714,65 @@ func TestUltraDNSProvider_DomainFiltersZonesFailCase(t *testing.T) { assert.NotNilf(t, err, " Multiple domain filter failed %s", "formatted") } } + +//zones function with domain filter test scenario +func TestUltraDNSProvider_DomainFilterZonesMocked(t *testing.T) { + mocked := mockUltraDNSZone{} + provider := &UltraDNSProvider{ + client: udnssdk.Client{ + Zone: &mocked, + }, + domainFilter: endpoint.NewDomainFilter([]string{"test-ultradns-provider.com."}), + } + + zoneKey := &udnssdk.ZoneKey{ + Zone: "test-ultradns-provider.com.", + AccountName: "", + } + + // When AccountName not given + expected, _, _, err := provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) + assert.Nil(t, err) + zones, err := provider.Zones(context.Background()) + assert.Nil(t, err) + assert.Equal(t, reflect.DeepEqual(expected, zones), true) + + // When AccountName is set + provider = &UltraDNSProvider{ + client: udnssdk.Client{ + Zone: &mocked, + }, + domainFilter: endpoint.NewDomainFilter([]string{"test-ultradns-provider.com."}), + AccountName: "teamrest", + } + + zoneKey = &udnssdk.ZoneKey{ + Zone: "test-ultradns-provider.com.", + AccountName: "teamrest", + } + + expected, _, _, err = provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) + assert.Nil(t, err) + zones, err = provider.Zones(context.Background()) + assert.Nil(t, err) + assert.Equal(t, reflect.DeepEqual(expected, zones), true) + + //When zone is not given but account is provided + provider = &UltraDNSProvider{ + client: udnssdk.Client{ + Zone: &mocked, + }, + AccountName: "teamrest", + } + + zoneKey = &udnssdk.ZoneKey{ + AccountName: "teamrest", + } + + expected, _, _, err = provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) + assert.Nil(t, err) + zones, err = provider.Zones(context.Background()) + assert.Nil(t, err) + assert.Equal(t, reflect.DeepEqual(expected, zones), true) + +} From a2027755c9c3c803a8046ebcb435ad060e28c1ce Mon Sep 17 00:00:00 2001 From: kbhandari Date: Tue, 16 Jun 2020 19:07:19 +0000 Subject: [PATCH 6/8] Added fix for default TTL --- docs/ttl.md | 2 +- docs/tutorials/ultradns.md | 7 +++-- go.mod | 3 +- go.sum | 6 ++-- provider/ultradns.go | 57 +++++++++++++++----------------------- 5 files changed, 34 insertions(+), 41 deletions(-) diff --git a/docs/ttl.md b/docs/ttl.md index db1cc15e0..327c61f50 100644 --- a/docs/ttl.md +++ b/docs/ttl.md @@ -79,4 +79,4 @@ The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 6 The Vultr provider minimal TTL is used when the TTL is 0. The default is 1 hour. ### UltraDNS -The UltraDNS provider minimal TTL is used when the TTL is 0. The default is 24 hour. +The UltraDNS provider minimal TTL is used when the TTL is not given. The default ttl is account level ttl and if account level ttl is not defined then it is 24 hour. diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md index 98b4a9793..aa8f664fb 100644 --- a/docs/tutorials/ultradns.md +++ b/docs/tutorials/ultradns.md @@ -207,7 +207,8 @@ Now that we have verified that ExternalDNS will automatically manage your UltraD $ kubectl delete service -f nginx.yaml $ kubectl delete service -f externaldns.yaml ``` -## Creating Multiple A Records Target +## Example to Manage your Records +### Creating Multiple A Records Target - First, you want to create a service file called 'apple-banana-echo.yaml' ```yaml --- @@ -268,7 +269,7 @@ $ kubectl delete -f apple-banana-echo.yaml $ kubectl delete -f expose-apple-banana-app.yaml $ kubectl delete -f external-dns.yaml ``` -## Creating CNAME Record +### Creating CNAME Record - Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. If this not provided, your records will not be created. - First, create a service file called 'apple-banana-echo.yaml' - _Config File Example – kubernetes cluster is on-premise not on cloud_ @@ -358,7 +359,7 @@ $ kubectl create -f external-dns.yaml $ kubectl delete -f apple-banana-echo.yaml $ kubectl delete -f external-dns.yaml ``` -## Create Multiple Types Of Records +### Creating Multiple Types Of Records - Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. Since you will also be created a CNAME record, If this not provided, your records will not be created. - First, create a service file called 'apple-banana-echo.yaml' - _Config File Example – kubernetes cluster is on-premise not on cloud_ diff --git a/go.mod b/go.mod index b017db91a..025f5702f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/alecthomas/colour v0.1.0 // indirect github.com/alecthomas/kingpin v2.2.5+incompatible github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect - github.com/ultradns/ultradns-sdk-go v1.3.7 github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f github.com/aws/aws-sdk-go v1.27.4 github.com/cloudflare/cloudflare-go v0.10.1 @@ -50,7 +49,9 @@ require ( github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect github.com/smartystreets/gunit v1.1.1 // indirect github.com/stretchr/testify v1.4.0 + github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/transip/gotransip v5.8.2+incompatible + github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4 github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 github.com/vultr/govultr v0.3.2 go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 diff --git a/go.sum b/go.sum index 7608ffbe3..3a165e540 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5Vpd github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/ultradns/ultradns-sdk-go v1.3.7 h1:sGeLtpu5atyi4aXEM18aEz0DpTFyhREhCSfkx4RojfU= -github.com/ultradns/ultradns-sdk-go v1.3.7/go.mod h1:vCC5SBZUcMRpcfma80Aw0Xk11WxOgbDA071AUban7ws= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0= @@ -583,6 +581,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= +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/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= 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 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= @@ -594,6 +594,8 @@ github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WV github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4 h1:o4HSecSlhMcumDd5eLFnMblL20+RVpSBeVxelxO875w= +github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4/go.mod h1:43vmy6GEvRuVMpGEWfJ/JoEM6RIqUQI1/tb8JqZR1zI= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU= diff --git a/provider/ultradns.go b/provider/ultradns.go index 84ef2dc06..c988b8708 100644 --- a/provider/ultradns.go +++ b/provider/ultradns.go @@ -29,13 +29,12 @@ import ( ) const ( - ultradnsDefaultTTL = 198 - ultradnsCreate = "CREATE" - ultradnsDelete = "DELETE" - ultradnsUpdate = "UPDATE" - sbPoolPriority = 1 - sbPoolOrder = "ROUND_ROBIN" - rdPoolOrder = "ROUND_ROBIN" + ultradnsCreate = "CREATE" + ultradnsDelete = "DELETE" + ultradnsUpdate = "UPDATE" + sbPoolPriority = 1 + sbPoolOrder = "ROUND_ROBIN" + rdPoolOrder = "ROUND_ROBIN" ) // global variables @@ -140,45 +139,35 @@ func NewUltraDNSProvider(domainFilter endpoint.DomainFilter, dryRun bool) (*Ultr func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { zoneKey := &udnssdk.ZoneKey{} zones_appender := []udnssdk.Zone{} + zones := []udnssdk.Zone{} + var err error if p.domainFilter.IsConfigured() { for _, zone := range p.domainFilter.Filters { if p.AccountName != "" { - zoneKey = &udnssdk.ZoneKey{ - Zone: zone, - AccountName: p.AccountName, - } - - zones, err := p.fetchZones(ctx, zoneKey) - if err != nil { - return nil, err - } - - zones_appender = append(zones_appender, zones...) + zoneKey.Zone = zone + zoneKey.AccountName = p.AccountName + zones, err = p.fetchZones(ctx, zoneKey) } else { - zoneKey = &udnssdk.ZoneKey{ - Zone: zone, - } - - zones, err := p.fetchZones(ctx, zoneKey) - if err != nil { - return nil, err - } - - zones_appender = append(zones_appender, zones...) + zoneKey.Zone = zone + zones, err = p.fetchZones(ctx, zoneKey) } + + if err != nil { + return nil, err + } + + zones_appender = append(zones_appender, zones...) + } return zones_appender, nil } else { if p.AccountName != "" { - zoneKey = &udnssdk.ZoneKey{ - Zone: "", - AccountName: p.AccountName, - } + zoneKey.AccountName = p.AccountName } zones, err := p.fetchZones(ctx, zoneKey) @@ -226,7 +215,7 @@ func (p *UltraDNSProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, e name = zone.Properties.Name } - endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL), r.RData...) + endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL.(float64)), r.RData...) endpoints = append(endpoints, endPointTTL) } } @@ -449,7 +438,7 @@ func (p *UltraDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Chang func newUltraDNSChanges(action string, endpoints []*endpoint.Endpoint) []*UltraDNSChanges { changes := make([]*UltraDNSChanges, 0, len(endpoints)) - ttl := ultradnsDefaultTTL + var ttl interface{} for _, e := range endpoints { if e.RecordTTL.IsConfigured() { From 7a71b2932abf6c46ff377cf934d3a9528c5d841b Mon Sep 17 00:00:00 2001 From: kbhandari Date: Tue, 16 Jun 2020 20:15:32 +0000 Subject: [PATCH 7/8] Added final review comments --- docs/ttl.md | 2 +- docs/tutorials/ultradns.md | 2 +- provider/ultradns.go | 22 ++++++---------------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/docs/ttl.md b/docs/ttl.md index 327c61f50..cfab65baf 100644 --- a/docs/ttl.md +++ b/docs/ttl.md @@ -79,4 +79,4 @@ The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 6 The Vultr provider minimal TTL is used when the TTL is 0. The default is 1 hour. ### UltraDNS -The UltraDNS provider minimal TTL is used when the TTL is not given. The default ttl is account level ttl and if account level ttl is not defined then it is 24 hour. +The UltraDNS provider minimal TTL is used when the TTL is not provided. The default TTL is account level default TTL, if defined, otherwise 24 hours. diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md index aa8f664fb..8b2d38fdf 100644 --- a/docs/tutorials/ultradns.md +++ b/docs/tutorials/ultradns.md @@ -207,7 +207,7 @@ Now that we have verified that ExternalDNS will automatically manage your UltraD $ kubectl delete service -f nginx.yaml $ kubectl delete service -f externaldns.yaml ``` -## Example to Manage your Records +## Examples to Manage your Records ### Creating Multiple A Records Target - First, you want to create a service file called 'apple-banana-echo.yaml' ```yaml diff --git a/provider/ultradns.go b/provider/ultradns.go index c988b8708..cfba0d455 100644 --- a/provider/ultradns.go +++ b/provider/ultradns.go @@ -144,16 +144,9 @@ func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { if p.domainFilter.IsConfigured() { for _, zone := range p.domainFilter.Filters { - if p.AccountName != "" { - zoneKey.Zone = zone - zoneKey.AccountName = p.AccountName - zones, err = p.fetchZones(ctx, zoneKey) - - } else { - - zoneKey.Zone = zone - zones, err = p.fetchZones(ctx, zoneKey) - } + zoneKey.Zone = zone + zoneKey.AccountName = p.AccountName + zones, err = p.fetchZones(ctx, zoneKey) if err != nil { return nil, err @@ -166,10 +159,7 @@ func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { return zones_appender, nil } else { - if p.AccountName != "" { - zoneKey.AccountName = p.AccountName - } - + zoneKey.AccountName = p.AccountName zones, err := p.fetchZones(ctx, zoneKey) if err != nil { return nil, err @@ -215,7 +205,7 @@ func (p *UltraDNSProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, e name = zone.Properties.Name } - endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL.(float64)), r.RData...) + endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL), r.RData...) endpoints = append(endpoints, endPointTTL) } } @@ -438,7 +428,7 @@ func (p *UltraDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Chang func newUltraDNSChanges(action string, endpoints []*endpoint.Endpoint) []*UltraDNSChanges { changes := make([]*UltraDNSChanges, 0, len(endpoints)) - var ttl interface{} + var ttl int for _, e := range endpoints { if e.RecordTTL.IsConfigured() { From f5db378090f7bbfac898752952be623fad6fa15f Mon Sep 17 00:00:00 2001 From: kbhandari Date: Tue, 16 Jun 2020 20:35:57 +0000 Subject: [PATCH 8/8] Made go.mod and go.sunm file changes --- docs/tutorials/ultradns.md | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md index 8b2d38fdf..84af06564 100644 --- a/docs/tutorials/ultradns.md +++ b/docs/tutorials/ultradns.md @@ -433,7 +433,6 @@ $ kubectl delete -f external-dns.yaml app: apple2 ports: - port: 5680 # Default port for image - apiVersion: extensions/v1beta1 --- apiVersion: extensions/v1beta1 kind: Ingress @@ -562,6 +561,7 @@ $ kubectl delete -f external-dns.yaml args: - "-text=apple" --- + apiVersion: extensions/v1beta1 kind: Service apiVersion: v1 metadata: diff --git a/go.mod b/go.mod index 025f5702f..d6f616d89 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( github.com/stretchr/testify v1.4.0 github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/transip/gotransip v5.8.2+incompatible - github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4 + github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60 github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 github.com/vultr/govultr v0.3.2 go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875 diff --git a/go.sum b/go.sum index 3a165e540..1fed7d8db 100644 --- a/go.sum +++ b/go.sum @@ -594,8 +594,8 @@ github.com/uber/jaeger-client-go v0.0.0-20190228190846-ecf2d03a9e80/go.mod h1:WV github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4 h1:o4HSecSlhMcumDd5eLFnMblL20+RVpSBeVxelxO875w= -github.com/ultradns/ultradns-sdk-go v0.0.0-20200616162335-c89b197deaf4/go.mod h1:43vmy6GEvRuVMpGEWfJ/JoEM6RIqUQI1/tb8JqZR1zI= +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/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/vinyldns/go-vinyldns v0.0.0-20190611170422-7119fe55ed92 h1:Q76MzqJu++vAfhj0mVf7t0F4xHUbg+V/d/Uk5PBQjRU=