diff --git a/OWNERS b/OWNERS index 8ee1d2f0c..b9d702e10 100644 --- a/OWNERS +++ b/OWNERS @@ -51,6 +51,6 @@ filters: "provider/cloudflare": labels: - provider/cloudflare - "provider/(akamai|alibabacloud|civo|designate|digitalocean|dnsimple|exoscale|gandi|godaddy|linode|ns1|oci|ovh|pihole|plural|scaleway|transip|ultradns)": + "provider/(akamai|alibabacloud|civo|designate|digitalocean|dnsimple|exoscale|gandi|godaddy|linode|ns1|oci|ovh|pihole|plural|scaleway|transip)": labels: - provider diff --git a/README.md b/README.md index 9d69b0720..0adde245c 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,6 @@ The following table clarifies the current status of the providers according to t | TransIP | Alpha | | | OVHcloud | Beta | @rbeuque74 | | Scaleway DNS | Alpha | @Sh4d1 | -| UltraDNS | Alpha | | | GoDaddy | Alpha | | | Gandi | Alpha | @packi | | Plural | Alpha | @michaeljguarino | @@ -206,7 +205,6 @@ The following tutorials are provided: - [TransIP](docs/tutorials/transip.md) - [OVHcloud](docs/tutorials/ovh.md) - [Scaleway](docs/tutorials/scaleway.md) -- [UltraDNS](docs/tutorials/ultradns.md) - [GoDaddy](docs/tutorials/godaddy.md) - [Gandi](docs/tutorials/gandi.md) - [Nodes as source](docs/sources/nodes.md) diff --git a/controller/execute.go b/controller/execute.go index 7d76aab25..c4dcd5612 100644 --- a/controller/execute.go +++ b/controller/execute.go @@ -64,7 +64,6 @@ import ( "sigs.k8s.io/external-dns/provider/rfc2136" "sigs.k8s.io/external-dns/provider/scaleway" "sigs.k8s.io/external-dns/provider/transip" - "sigs.k8s.io/external-dns/provider/ultradns" "sigs.k8s.io/external-dns/provider/webhook" webhookapi "sigs.k8s.io/external-dns/provider/webhook/api" "sigs.k8s.io/external-dns/registry" @@ -187,8 +186,6 @@ func Execute() { p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.AzureZonesCacheDuration, cfg.AzureMaxRetriesCount, cfg.DryRun) case "azure-private-dns": p, err = azure.NewAzurePrivateDNSProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureSubscriptionID, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.AzureActiveDirectoryAuthorityHost, cfg.AzureZonesCacheDuration, cfg.AzureMaxRetriesCount, cfg.DryRun) - case "ultradns": - p, err = ultradns.NewUltraDNSProvider(domainFilter, cfg.DryRun) case "civo": p, err = civo.NewCivoProvider(domainFilter, cfg.DryRun) case "cloudflare": diff --git a/docs/advanced/ttl.md b/docs/advanced/ttl.md index 5cc19bebf..5cc837e55 100644 --- a/docs/advanced/ttl.md +++ b/docs/advanced/ttl.md @@ -43,7 +43,6 @@ TTL must be a positive value. - [x] Linode - [x] TransIP - [x] RFC2136 -- [x] UltraDNS PRs welcome! @@ -90,7 +89,3 @@ The Linode Provider default TTL is used when the TTL is 0. The default is 24 hou ### TransIP Provider The TransIP Provider minimal TTL is used when the TTL is 0. The minimal TTL is 60s. - -### UltraDNS - -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/flags.md b/docs/flags.md index a8284b7f1..231b5b18e 100644 --- a/docs/flags.md +++ b/docs/flags.md @@ -51,7 +51,7 @@ | `--target-net-filter=TARGET-NET-FILTER` | Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional) | | `--[no-]traefik-disable-legacy` | Disable listeners on Resources under the traefik.containo.us API Group | | `--[no-]traefik-disable-new` | Disable listeners on Resources under the traefik.io API Group | -| `--provider=provider` | The DNS provider where the DNS records will be created (required, options: akamai, alibabacloud, aws, aws-sd, azure, azure-dns, azure-private-dns, civo, cloudflare, coredns, digitalocean, dnsimple, exoscale, gandi, godaddy, google, inmemory, linode, ns1, oci, ovh, pdns, pihole, plural, rfc2136, scaleway, skydns, transip, ultradns, webhook) | +| `--provider=provider` | The DNS provider where the DNS records will be created (required, options: akamai, alibabacloud, aws, aws-sd, azure, azure-dns, azure-private-dns, civo, cloudflare, coredns, digitalocean, dnsimple, exoscale, gandi, godaddy, google, inmemory, linode, ns1, oci, ovh, pdns, pihole, plural, rfc2136, scaleway, skydns, transip, webhook) | | `--provider-cache-time=0s` | The time to cache the DNS provider record list requests. | | `--domain-filter=` | Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional) | | `--exclude-domains=` | Exclude subdomains (optional) | diff --git a/docs/providers.md b/docs/providers.md index f601ac972..228622939 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -29,5 +29,4 @@ Provider supported configurations | RFC2136 | n/a | yes | n/a | | Scaleway | n/a | n/a | 300 | | Transip | n/a | yes | 60 | -| Ultradns | n/a | yes | n/a | | Webhook | n/a | n/a | n/a | diff --git a/docs/tutorials/ultradns.md b/docs/tutorials/ultradns.md deleted file mode 100644 index b83d15319..000000000 --- a/docs/tutorials/ultradns.md +++ /dev/null @@ -1,665 +0,0 @@ -# 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.com/) - -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.k8s.io/external-dns/external-dns:v0.17.0 - 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/v1 -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","watch"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: external-dns-viewer -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: external-dns -subjects: -- kind: ServiceAccount - name: external-dns - namespace: default ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: external-dns -spec: - strategy: - type: Recreate - selector: - matchLabels: - app: external-dns - template: - metadata: - labels: - app: external-dns - spec: - serviceAccountName: external-dns - containers: - - name: external-dns - image: registry.k8s.io/external-dns/external-dns:v0.17.0 - 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.com/login) that the records are created under the zone "example.com". - -For more information on UltraDNS UI, refer to (https://docs.ultradns.com/Content/MSP_User_Guide/Content/User%20Guides/MSP_User_Guide/Navigation/Moving%20Around%20the%20UI.htm#_Toc2780722). - -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: - -```sh -kubectl delete service -f nginx.yaml -kubectl delete service -f externaldns.yaml -``` - -## Examples to Manage your Records - -### 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: example-app - labels: - app: apple -spec: - containers: - - name: example-app - image: hashicorp/http-echo - args: - - "-text=apple" ---- -kind: Service -apiVersion: v1 -metadata: - name: example-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: networking.k8s.io/v1 -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 - pathType: Prefix - backend: - service: - name: example-service - port: - number: 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.com/login) 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: example-app - labels: - app: apple - spec: - containers: - - name: example-app - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-service - spec: - selector: - app: apple - ports: - - port: 5678 # Default port for image - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service - port: - number: 5678 - ``` - - - _Config File Example – Kubernetes cluster service from different cloud vendors_ - - ```yaml - --- - kind: Pod - apiVersion: v1 - metadata: - name: example-app - labels: - app: apple - spec: - containers: - - name: example-app - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-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.com/login), 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 -``` - -### 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_ - - ```yaml - --- - kind: Pod - apiVersion: v1 - metadata: - name: example-app - labels: - app: apple - spec: - containers: - - name: example-app - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-service - spec: - selector: - app: apple - ports: - - port: 5678 # Default port for image - --- - kind: Pod - apiVersion: v1 - metadata: - name: example-app1 - labels: - app: apple1 - spec: - containers: - - name: example-app1 - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-service1 - spec: - selector: - app: apple1 - ports: - - port: 5679 # Default port for image - --- - kind: Pod - apiVersion: v1 - metadata: - name: example-app2 - labels: - app: apple2 - spec: - containers: - - name: example-app2 - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-service2 - spec: - selector: - app: apple2 - ports: - - port: 5680 # Default port for image - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service - port: - number: 5678 - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service1 - port: - number: 5679 - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service2 - port: - number: 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: example-app - labels: - app: apple - spec: - containers: - - name: example-app - image: hashicorp/http-echo - args: - - "-text=apple" - --- - kind: Service - apiVersion: v1 - metadata: - name: example-service - spec: - selector: - app: apple - ports: - - port: 5678 # Default port for image - --- - kind: Pod - apiVersion: v1 - metadata: - name: example-app1 - labels: - app: apple1 - spec: - containers: - - name: example-app1 - image: hashicorp/http-echo - args: - - "-text=apple" - --- - apiVersion: extensions/v1beta1 - kind: Service - apiVersion: v1 - metadata: - name: example-service1 - spec: - selector: - app: apple1 - ports: - - port: 5679 # Default port for image - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service - port: - number: 5678 - --- - apiVersion: networking.k8s.io/v1 - 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: - service: - name: example-service1 - port: - number: 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. -- Please verify on the [UltraDNS UI](https://portal.ultradns.com/login), 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 e2d2a35fa..ffb29504f 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,6 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 github.com/transip/gotransip/v6 v6.26.0 - github.com/ultradns/ultradns-sdk-go v1.3.7 go.etcd.io/etcd/client/v3 v3.6.0 go.uber.org/ratelimit v0.3.1 golang.org/x/net v0.40.0 @@ -102,7 +101,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/fatih/structs v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -143,7 +141,6 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -164,7 +161,6 @@ require ( github.com/sosodev/duration v1.3.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/vektah/gqlparser/v2 v2.5.25 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index abeae1fc8..798796933 100644 --- a/go.sum +++ b/go.sum @@ -298,8 +298,6 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM= @@ -740,8 +738,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -994,8 +990,6 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/terra-farm/udnssdk v1.3.5 h1:MNR3adfuuEK/l04+jzo8WW/0fnorY+nW515qb3vEr6I= -github.com/terra-farm/udnssdk v1.3.5/go.mod h1:8RnM56yZTR7mYyUIvrDgXzdRaEyFIzqdEi7+um26Sv8= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -1012,8 +1006,6 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ultradns/ultradns-sdk-go v1.3.7 h1:P4CaM+npeXIybbLL27ezR316NnyILI1Y8IvfZtNE+Co= -github.com/ultradns/ultradns-sdk-go v1.3.7/go.mod h1:43vmy6GEvRuVMpGEWfJ/JoEM6RIqUQI1/tb8JqZR1zI= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index b04c5aa41..48a2ba3e2 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -487,7 +487,7 @@ func App(cfg *Config) *kingpin.Application { app.Flag("traefik-disable-new", "Disable listeners on Resources under the traefik.io API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableNew)).BoolVar(&cfg.TraefikDisableNew) // Flags related to providers - providers := []string{"akamai", "alibabacloud", "aws", "aws-sd", "azure", "azure-dns", "azure-private-dns", "civo", "cloudflare", "coredns", "digitalocean", "dnsimple", "exoscale", "gandi", "godaddy", "google", "inmemory", "linode", "ns1", "oci", "ovh", "pdns", "pihole", "plural", "rfc2136", "scaleway", "skydns", "transip", "ultradns", "webhook"} + providers := []string{"akamai", "alibabacloud", "aws", "aws-sd", "azure", "azure-dns", "azure-private-dns", "civo", "cloudflare", "coredns", "digitalocean", "dnsimple", "exoscale", "gandi", "godaddy", "google", "inmemory", "linode", "ns1", "oci", "ovh", "pdns", "pihole", "plural", "rfc2136", "scaleway", "skydns", "transip", "webhook"} app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: "+strings.Join(providers, ", ")+")").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, providers...) app.Flag("provider-cache-time", "The time to cache the DNS provider record list requests.").Default(defaultConfig.ProviderCacheTime.String()).DurationVar(&cfg.ProviderCacheTime) app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter) diff --git a/provider/ultradns/ultradns.go b/provider/ultradns/ultradns.go deleted file mode 100644 index 1b2f2297a..000000000 --- a/provider/ultradns/ultradns.go +++ /dev/null @@ -1,498 +0,0 @@ -/* -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 ultradns - -import ( - "context" - "encoding/base64" - "fmt" - "os" - "strconv" - "strings" - "time" - - log "github.com/sirupsen/logrus" - udnssdk "github.com/ultradns/ultradns-sdk-go" - - "sigs.k8s.io/external-dns/endpoint" - "sigs.k8s.io/external-dns/plan" - "sigs.k8s.io/external-dns/provider" -) - -const ( - ultradnsCreate = "CREATE" - ultradnsDelete = "DELETE" - ultradnsUpdate = "UPDATE" - sbPoolPriority = 1 - sbPoolOrder = "ROUND_ROBIN" - rdPoolOrder = "ROUND_ROBIN" -) - -var ( - sbPoolActOnProbes = true - ultradnsPoolType = "rdpool" - accountName string - sbPoolRunProbes = true - // Setting custom headers for ultradns api calls - customHeader = []udnssdk.CustomHeader{ - { - Key: "UltraClient", - Value: "kube-client", - }, - } -) - -// UltraDNSProvider struct -type UltraDNSProvider struct { - provider.BaseProvider - client udnssdk.Client - domainFilter endpoint.DomainFilter - dryRun bool -} - -// UltraDNSChanges struct -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") - } - 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") - } - 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") - } - - return &UltraDNSProvider{ - client: *client, - domainFilter: domainFilter, - dryRun: dryRun, - }, nil -} - -// Zones returns list of hosted zones -func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) { - zoneKey := &udnssdk.ZoneKey{} - var err error - - if p.domainFilter.IsConfigured() { - zonesAppender := []udnssdk.Zone{} - for _, zone := range p.domainFilter.Filters { - zoneKey.Zone = zone - zoneKey.AccountName = accountName - zones, err := p.fetchZones(ctx, zoneKey) - if err != nil { - return nil, err - } - - zonesAppender = append(zonesAppender, zones...) - } - return zonesAppender, nil - } - zoneKey.AccountName = 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) - var rrsetType string - var ownerName string - 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 provider.SupportedRecordType(recordTypeArray[0]) { - log.Infof("owner name %s", r.OwnerName) - name := 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) { - // Logic to paginate through all available results - maxerrs := 5 - waittime := 5 * time.Second - - var 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 - } - rrsets = append(rrsets, reqRrsets...) - - 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) { - // Logic to paginate through all available results - offset := 0 - limit := 1000 - maxerrs := 5 - waittime := 5 * time.Second - - zones := []udnssdk.Zone{} - - errcnt := 0 - - 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 - } - - zones = append(zones, reqZones...) - 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 { - switch change.ResourceRecordSetUltraDNS.RRType { - case "CNAME": - cnameownerName = change.ResourceRecordSetUltraDNS.OwnerName - case "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 { - _, 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 { - 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 { - _, 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 { - _, 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)) - var ttl int - 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 := provider.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) - } - - 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/ultradns_test.go b/provider/ultradns/ultradns_test.go deleted file mode 100644 index d0b9bddcd..000000000 --- a/provider/ultradns/ultradns_test.go +++ /dev/null @@ -1,756 +0,0 @@ -/* -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 ultradns - -import ( - "context" - "encoding/json" - "fmt" - "log" - "net/http" - "os" - "reflect" - _ "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - udnssdk "github.com/ultradns/ultradns-sdk-go" - - "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(_ udnssdk.RRSetKey, _ udnssdk.RRSet) (*http.Response, error) { - return &http.Response{}, nil -} - -func (m *mockUltraDNSRecord) Select(_ 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 &http.Response{}, nil -} - -func (m *mockUltraDNSRecord) Delete(k udnssdk.RRSetKey) (*http.Response, error) { - return &http.Response{}, 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.NoError(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.Errorf(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) - require.NoError(t, err) - zones, err := provider.Zones(context.Background()) - require.NoError(t, err) - assert.True(t, reflect.DeepEqual(expected, zones)) -} - -// 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()) - require.NoError(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.NoErrorf(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.NoError(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.Error(t, err) -} - -// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be available "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) - require.NoError(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, "1.1.1.1", rrsets[0].RData[0]) - - 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, "2001:db8:85a3:0:0:8a2e:370:7334", rrsets[0].RData[0]) - - 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) - require.NoError(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, "1.1.2.2", rrsets[0].RData[0]) - - 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, "2001:db8:85a3:0:0:8a2e:370:7335", rrsets[0].RData[0]) - - 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) - require.NoError(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, "404 Not Found", resp.Status) - - resp, _ = providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{}) - assert.Equal(t, "404 Not Found", resp.Status) - - } -} - -// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be available "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.NoError(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, []string{"1.1.1.1", "1.1.2.2"}, rrsets[0].RData) - - 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) - require.NoError(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, []string{"1.1.2.2", "192.168.0.24", "1.2.3.4"}, rrsets[0].RData) - - 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.NoError(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, []string{"1.1.2.2"}, rrsets[0].RData) - - 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.NoError(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, "404 Not Found", resp.Status) - - } -} - -// 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.Errorf(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, "404 Not Found", resp.Status) - _ = 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) - require.NoErrorf(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, "200 OK", resp.Status) - - 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) - require.NoError(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, "404 Not Found", resp.Status) - } -} - -// 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.Errorf(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, "404 Not Found", resp.Status) - } -} - -// 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.Errorf(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.Errorf(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.Errorf(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.Errorf(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.Errorf(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.NoError(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.NoErrorf(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.NoErrorf(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.NoErrorf(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.Errorf(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.NoErrorf(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, "200 OK", resp.Status) - - // Converting 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.NoError(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, "200 OK", resp.Status) - - // Converting 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.NoError(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, "200 OK", resp.Status) - - // 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.NoError(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, "404 Not Found", resp.Status) - } -} - -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, "kubernetes-ultradns-provider-test.com.", zones[0].Properties.Name) - assert.Equal(t, "kubernetes-ultradns-provider-test.com.", zones[1].Properties.Name) - assert.NoErrorf(t, err, " Multiple domain filter failed %s", "formatted") - - provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{}), true) - zones, err = provider.Zones(context.Background()) - assert.NoErrorf(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.Errorf(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.NoError(t, err) - zones, err := provider.Zones(context.Background()) - assert.NoError(t, err) - assert.True(t, reflect.DeepEqual(expected, zones)) - accountName = "teamrest" - // When AccountName is set - provider = &UltraDNSProvider{ - client: udnssdk.Client{ - Zone: &mocked, - }, - domainFilter: endpoint.NewDomainFilter([]string{"test-ultradns-provider.com."}), - } - - zoneKey = &udnssdk.ZoneKey{ - Zone: "test-ultradns-provider.com.", - AccountName: "teamrest", - } - - expected, _, _, err = provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) - assert.NoError(t, err) - zones, err = provider.Zones(context.Background()) - assert.NoError(t, err) - assert.True(t, reflect.DeepEqual(expected, zones)) - - // When zone is not given but account is provided - provider = &UltraDNSProvider{ - client: udnssdk.Client{ - Zone: &mocked, - }, - } - - zoneKey = &udnssdk.ZoneKey{ - AccountName: "teamrest", - } - - expected, _, _, err = provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000) - assert.NoError(t, err) - zones, err = provider.Zones(context.Background()) - assert.NoError(t, err) - assert.True(t, reflect.DeepEqual(expected, zones)) -}