remove ultradns provider

This commit is contained in:
Michel Loiseleur 2025-05-25 10:09:11 +02:00
parent 640e593fcb
commit a48b75b266
12 changed files with 3 additions and 1945 deletions

2
OWNERS
View File

@ -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

View File

@ -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)

View File

@ -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":

View File

@ -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.

View File

@ -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) |

View File

@ -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 |

View File

@ -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```

4
go.mod
View File

@ -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

8
go.sum
View File

@ -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=

View File

@ -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)

View File

@ -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
}

View File

@ -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))
}