mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 01:26:59 +02:00
Finalized version of ultradns provider
This commit is contained in:
parent
844b787dba
commit
db3fdfb1d9
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
@ -65,5 +65,5 @@ provider/vinyldns: provider/vinyldns*
|
||||
# Add 'provider/vultr' in file which starts with vultr
|
||||
provider/vultr: provider/vultr*
|
||||
|
||||
# Add 'provider/ultradns' in file which starts with vultr
|
||||
provider/vultr: provider/ultradns*
|
||||
# Add 'provider/ultradns' in file which starts with ultradns
|
||||
provider/ultradns: provider/ultradns*
|
||||
|
619
docs/tutorials/ultradns.md
Normal file
619
docs/tutorials/ultradns.md
Normal file
@ -0,0 +1,619 @@
|
||||
# Setting up ExternalDNS for Services on UltraDNS
|
||||
|
||||
This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster using UltraDNS.
|
||||
|
||||
For this tutorial, please make sure that you are using a version **> 0.7.2** of ExternalDNS.
|
||||
|
||||
## Managing DNS with UltraDNS
|
||||
|
||||
If you would like to read-up on the UltraDNS service, you can find additional details here: [Introduction to UltraDNS](https://docs.ultradns.neustar)
|
||||
|
||||
Before proceeding, please create a new DNS Zone that you will create your records in for this tutorial process. For the examples in this tutorial, we will be using `example.com` as our Zone.
|
||||
|
||||
## Setting Up UltraDNS Credentials
|
||||
|
||||
The following environment variables will be needed to run ExternalDNS with UltraDNS.
|
||||
|
||||
`ULTRADNS_USERNAME`,`ULTRADNS_PASSWORD`, &`ULTRADNS_BASEURL`
|
||||
`ULTRADNS_ACCOUNTNAME`(optional variable).
|
||||
|
||||
## Deploying ExternalDNS
|
||||
|
||||
Connect your `kubectl` client to the cluster you want to test ExternalDNS with.
|
||||
Then, apply one of the following manifests file to deploy ExternalDNS.
|
||||
|
||||
- Note: We are assuming the zone is already present within UltraDNS.
|
||||
- Note: While creating CNAMES as target endpoints, the `--txt-prefix` option is mandatory.
|
||||
### Manifest (for clusters without RBAC enabled)
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: external-dns
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: external-dns
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: external-dns
|
||||
spec:
|
||||
containers:
|
||||
- name: external-dns
|
||||
image: registry.opensource.zalan.do/teapot/external-dns:latest
|
||||
args:
|
||||
- --source=service
|
||||
- --source=ingress # ingress is also possible
|
||||
- --domain-filter=example.com # (Recommended) We recommend to use this filter as it minimize the time to propagate changes, as there are less number of zones to look into..
|
||||
- --provider=ultradns
|
||||
- --txt-prefix=txt-
|
||||
env:
|
||||
- name: ULTRADNS_USERNAME
|
||||
value: ""
|
||||
- name: ULTRADNS_PASSWORD # The password is required to be BASE64 encrypted.
|
||||
value: ""
|
||||
- name: ULTRADNS_BASEURL
|
||||
value: "https://api.ultradns.com/"
|
||||
- name: ULTRADNS_ACCOUNTNAME
|
||||
value: ""
|
||||
```
|
||||
|
||||
### Manifest (for clusters with RBAC enabled)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: external-dns
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: external-dns
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["services","endpoints","pods"]
|
||||
verbs: ["get","watch","list"]
|
||||
- apiGroups: ["extensions"]
|
||||
resources: ["ingresses"]
|
||||
verbs: ["get","watch","list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: external-dns-viewer
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: external-dns
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: external-dns
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: external-dns
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: external-dns
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: external-dns
|
||||
spec:
|
||||
serviceAccountName: external-dns
|
||||
containers:
|
||||
- name: external-dns
|
||||
image: registry.opensource.zalan.do/teapot/external-dns:latest
|
||||
args:
|
||||
- --source=service
|
||||
- --source=ingress
|
||||
- --domain-filter=example.com #(Recommended) We recommend to use this filter as it minimize the time to propagate changes, as there are less number of zones to look into..
|
||||
- --provider=ultradns
|
||||
- --txt-prefix=txt-
|
||||
env:
|
||||
- name: ULTRADNS_USERNAME
|
||||
value: ""
|
||||
- name: ULTRADNS_PASSWORD # The password is required to be BASE64 encrypted.
|
||||
value: ""
|
||||
- name: ULTRADNS_BASEURL
|
||||
value: "https://api.ultradns.com/"
|
||||
- name: ULTRADNS_ACCOUNTNAME
|
||||
value: ""
|
||||
```
|
||||
|
||||
## Deploying an Nginx Service
|
||||
|
||||
Create a service file called 'nginx.yaml' with the following contents:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
annotations:
|
||||
external-dns.alpha.kubernetes.io/hostname: my-app.example.com.
|
||||
spec:
|
||||
selector:
|
||||
app: nginx
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 80
|
||||
```
|
||||
|
||||
Please note the annotation on the service. Use the same hostname as the UltraDNS zone created above.
|
||||
|
||||
ExternalDNS uses this annotation to determine what services should be registered with DNS. Removing the annotation will cause ExternalDNS to remove the corresponding DNS records.
|
||||
|
||||
## Creating the Deployment and Service:
|
||||
|
||||
```console
|
||||
$ kubectl create -f nginx.yaml
|
||||
$ kubectl create -f external-dns.yaml
|
||||
```
|
||||
|
||||
Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service.
|
||||
|
||||
Once the service has an external IP assigned, ExternalDNS will notice the new service IP address and will synchronize the UltraDNS records.
|
||||
|
||||
## Verifying UltraDNS Records
|
||||
|
||||
Please verify on the [UltraDNS UI](https://portal.ultradns.neustar) that the records are created under the zone "example.com".
|
||||
|
||||
For more information on UltraDNS UI, refer to (https://docs.ultradns.neustar/mspuserguide.html).
|
||||
|
||||
Select the zone that was created above (or select the appropriate zone if a different zone was used.)
|
||||
|
||||
The external IP address will be displayed as a CNAME record for your zone.
|
||||
|
||||
## Cleaning Up the Deployment and Service
|
||||
|
||||
Now that we have verified that ExternalDNS will automatically manage your UltraDNS records, you can delete example zones that you created in this tutorial:
|
||||
|
||||
```
|
||||
$ kubectl delete service -f nginx.yaml
|
||||
$ kubectl delete service -f externaldns.yaml
|
||||
```
|
||||
## Creating Multiple A Records Target
|
||||
- First, you want to create a service file called 'apple-banana-echo.yaml'
|
||||
```yaml
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app
|
||||
labels:
|
||||
app: apple
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service
|
||||
spec:
|
||||
selector:
|
||||
app: apple
|
||||
ports:
|
||||
- port: 5678 # Default port for image
|
||||
```
|
||||
- Then, create service file called 'expose-apple-banana-app.yaml' to expose the services. For more information to deploy ingress controller, refer to (https://kubernetes.github.io/ingress-nginx/deploy/)
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: 10.10.10.1,10.10.10.23
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service
|
||||
servicePort: 5678
|
||||
```
|
||||
- Then, create the deployment and service:
|
||||
```console
|
||||
$ kubectl create -f apple-banana-echo.yaml
|
||||
$ kubectl create -f expose-apple-banana-app.yaml
|
||||
$ kubectl create -f external-dns.yaml
|
||||
```
|
||||
- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service.
|
||||
- Please verify on the [UltraDNS UI](https://portal.ultradns.neustar) that the records have been created under the zone "example.com".
|
||||
- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone ‘example.com’:
|
||||
```console
|
||||
$ kubectl delete -f apple-banana-echo.yaml
|
||||
$ kubectl delete -f expose-apple-banana-app.yaml
|
||||
$ kubectl delete -f external-dns.yaml
|
||||
```
|
||||
## Creating CNAME Record
|
||||
- Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. If this not provided, your records will not be created.
|
||||
- First, create a service file called 'apple-banana-echo.yaml'
|
||||
- _Config File Example – kubernetes cluster is on-premise not on cloud_
|
||||
```yaml
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app
|
||||
labels:
|
||||
app: apple
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service
|
||||
spec:
|
||||
selector:
|
||||
app: apple
|
||||
ports:
|
||||
- port: 5678 # Default port for image
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: apple.cname.com.
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service
|
||||
servicePort: 5678
|
||||
```
|
||||
- _Config File Example – Kubernetes cluster service from different cloud vendors_
|
||||
```yaml
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app
|
||||
labels:
|
||||
app: apple
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service
|
||||
annotations:
|
||||
external-dns.alpha.kubernetes.io/hostname: my-app.example.com.
|
||||
spec:
|
||||
selector:
|
||||
app: apple
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5678
|
||||
targetPort: 5678
|
||||
```
|
||||
- Then, create the deployment and service:
|
||||
```console
|
||||
$ kubectl create -f apple-banana-echo.yaml
|
||||
$ kubectl create -f external-dns.yaml
|
||||
```
|
||||
- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service.
|
||||
- Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com".
|
||||
- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone "example.com":
|
||||
```console
|
||||
$ kubectl delete -f apple-banana-echo.yaml
|
||||
$ kubectl delete -f external-dns.yaml
|
||||
```
|
||||
## Create Multiple Types Of Records
|
||||
- Please note, that prior to deploying the external-dns service, you will need to add the option –txt-prefix=txt- into external-dns.yaml. Since you will also be created a CNAME record, If this not provided, your records will not be created.
|
||||
- First, create a service file called 'apple-banana-echo.yaml'
|
||||
- _Config File Example – kubernetes cluster is on-premise not on cloud_
|
||||
```yaml
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app
|
||||
labels:
|
||||
app: apple
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service
|
||||
spec:
|
||||
selector:
|
||||
app: apple
|
||||
ports:
|
||||
- port: 5678 # Default port for image
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app1
|
||||
labels:
|
||||
app: apple1
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app1
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service1
|
||||
spec:
|
||||
selector:
|
||||
app: apple1
|
||||
ports:
|
||||
- port: 5679 # Default port for image
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app2
|
||||
labels:
|
||||
app: apple2
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app2
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service2
|
||||
spec:
|
||||
selector:
|
||||
app: apple2
|
||||
ports:
|
||||
- port: 5680 # Default port for image
|
||||
apiVersion: extensions/v1beta1
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: apple.cname.com.
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service
|
||||
servicePort: 5678
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress1
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple-banana.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: 10.10.10.3
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service1
|
||||
servicePort: 5679
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress2
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: banana.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: 10.10.10.3,10.10.10.20
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service2
|
||||
servicePort: 5680
|
||||
```
|
||||
- _Config File Example – Kubernetes cluster service from different cloud vendors_
|
||||
```yaml
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
annotations:
|
||||
external-dns.alpha.kubernetes.io/hostname: my-app.example.com.
|
||||
spec:
|
||||
selector:
|
||||
app: nginx
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app
|
||||
labels:
|
||||
app: apple
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service
|
||||
spec:
|
||||
selector:
|
||||
app: apple
|
||||
ports:
|
||||
- port: 5678 # Default port for image
|
||||
---
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-app1
|
||||
labels:
|
||||
app: apple1
|
||||
spec:
|
||||
containers:
|
||||
- name: apple-app1
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-text=apple"
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: apple-service1
|
||||
spec:
|
||||
selector:
|
||||
app: apple1
|
||||
ports:
|
||||
- port: 5679 # Default port for image
|
||||
---
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: 10.10.10.3,10.10.10.25
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service
|
||||
servicePort: 5678
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example-ingress1
|
||||
annotations:
|
||||
ingress.kubernetes.io/rewrite-target: /
|
||||
ingress.kubernetes.io/scheme: internet-facing
|
||||
external-dns.alpha.kubernetes.io/hostname: apple-banana.example.com.
|
||||
external-dns.alpha.kubernetes.io/target: 10.10.10.3
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /apple
|
||||
backend:
|
||||
serviceName: apple-service1
|
||||
servicePort: 5679
|
||||
```
|
||||
- Then, create the deployment and service:
|
||||
```console
|
||||
$ kubectl create -f apple-banana-echo.yaml
|
||||
$ kubectl create -f external-dns.yaml
|
||||
```
|
||||
- Depending on where you run your service from, it can take a few minutes for your cloud provider to create an external IP for the service.
|
||||
-o Please verify on the [UltraDNS UI](https://portal.ultradns.neustar), that the records have been created under the zone "example.com".
|
||||
- Finally, you will need to clean up the deployment and service. Please verify on the UI afterwards that the records have been deleted from the zone "example.com":
|
||||
```console
|
||||
$ kubectl delete -f apple-banana-echo.yaml
|
||||
$ kubectl delete -f external-dns.yaml```
|
4
go.mod
4
go.mod
@ -14,6 +14,7 @@ require (
|
||||
github.com/alecthomas/colour v0.1.0 // indirect
|
||||
github.com/alecthomas/kingpin v2.2.5+incompatible
|
||||
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect
|
||||
github.com/ultradns/ultradns-sdk-go v1.3.7
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f
|
||||
github.com/aws/aws-sdk-go v1.27.4
|
||||
github.com/cloudflare/cloudflare-go v0.10.1
|
||||
@ -28,6 +29,7 @@ require (
|
||||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b // indirect
|
||||
github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f
|
||||
github.com/gophercloud/gophercloud v0.1.0
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/heptio/contour v0.15.0
|
||||
github.com/infobloxopen/infoblox-go-client v0.0.0-20180606155407-61dc5f9b0a65
|
||||
github.com/linki/instrumented_http v0.2.0
|
||||
@ -44,7 +46,7 @@ require (
|
||||
github.com/prometheus/client_golang v1.0.0
|
||||
github.com/sanyu/dynectsoap v0.0.0-20181203081243-b83de5edc4e0
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||
github.com/smartystreets/gunit v1.1.1 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
|
36
go.sum
36
go.sum
@ -71,12 +71,10 @@ github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAK
|
||||
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/ultradns/ultradns-sdk-go v1.3.7 h1:sGeLtpu5atyi4aXEM18aEz0DpTFyhREhCSfkx4RojfU=
|
||||
github.com/ultradns/ultradns-sdk-go v1.3.7/go.mod h1:vCC5SBZUcMRpcfma80Aw0Xk11WxOgbDA071AUban7ws=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v0.0.0-20180201100744-9d52b1fc8da9/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20180828111155-cad214d7d71f h1:hinXH9rcBjRoIih5tl4f1BCbNjOmPJ2UnZwcYDhEHR0=
|
||||
@ -96,8 +94,6 @@ github.com/aws/aws-sdk-go v1.27.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
@ -105,8 +101,6 @@ github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY=
|
||||
github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
@ -194,6 +188,7 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqL
|
||||
github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4/go.mod h1:SBHk9aNQtiw4R4bEuzHjVmZikkUKCnO1v3lPQ21HZGk=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99 h1:jmwW6QWvUO2OPe22YfgFvBaaZlSr8Rlrac5lZvG6IdM=
|
||||
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w9+vYGw2jUx2+2v03IA+phyQQjNRR4AL3uxlNrs=
|
||||
@ -206,7 +201,6 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ini/ini v1.33.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
@ -263,8 +257,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v15.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
@ -345,6 +337,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
|
||||
@ -374,8 +368,6 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jteeuwen/go-bindata v0.0.0-20180305030458-6025e8de665b/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
@ -394,6 +386,8 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@ -511,22 +505,16 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
@ -534,8 +522,6 @@ github.com/prometheus/procfs v0.0.0-20190403104016-ea9eea638872/go.mod h1:TjEm7z
|
||||
github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o=
|
||||
github.com/prometheus/prom2json v1.2.1/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
@ -561,6 +547,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@ -699,8 +687,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -732,8 +718,6 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
@ -764,8 +748,6 @@ golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDq
|
||||
golang.org/x/tools v0.0.0-20190822000311-fc82fb2afd64/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
|
2
main.go
2
main.go
@ -169,7 +169,7 @@ func main() {
|
||||
p, err = provider.NewVultrProvider(domainFilter, cfg.DryRun)
|
||||
|
||||
case "ultradns":
|
||||
p, err = provider.NewUltraDNSProvider(domainFilter, cfg.DryRun)
|
||||
p, err = provider.NewUltraDNSProvider(domainFilter, cfg.DryRun )
|
||||
|
||||
case "cloudflare":
|
||||
p, err = provider.NewCloudFlareProvider(domainFilter, zoneIDFilter, cfg.CloudflareZonesPerPage, cfg.CloudflareProxied, cfg.DryRun)
|
||||
|
@ -312,7 +312,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter)
|
||||
|
||||
// Flags related to providers
|
||||
app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr")
|
||||
app.Flag("provider", "The DNS provider where the DNS records will be created (required, options: aws, aws-sd, google, azure, azure-dns, azure-private-dns, cloudflare, rcodezero, digitalocean, dnsimple, akamai, infoblox, dyn, designate, coredns, skydns, inmemory, ovh, pdns, oci, exoscale, linode, rfc2136, ns1, transip, vinyldns, rdns, vultr, ultradns)").Required().PlaceHolder("provider").EnumVar(&cfg.Provider, "aws", "aws-sd", "google", "azure", "azure-dns", "azure-private-dns", "alibabacloud", "cloudflare", "rcodezero", "digitalocean", "dnsimple", "akamai", "infoblox", "dyn", "designate", "coredns", "skydns", "inmemory", "ovh", "pdns", "oci", "exoscale", "linode", "rfc2136", "ns1", "transip", "vinyldns", "rdns", "vultr", "ultradns")
|
||||
app.Flag("domain-filter", "Limit possible target zones by a domain suffix; specify multiple times for multiple domains (optional)").Default("").StringsVar(&cfg.DomainFilter)
|
||||
app.Flag("exclude-domains", "Exclude subdomains (optional)").Default("").StringsVar(&cfg.ExcludeDomains)
|
||||
app.Flag("zone-id-filter", "Filter target zones by hosted zone id; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.ZoneIDFilter)
|
||||
|
511
provider/ultradns.go
Normal file
511
provider/ultradns.go
Normal file
@ -0,0 +1,511 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
udnssdk "github.com/ultradns/ultradns-sdk-go"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
"sigs.k8s.io/external-dns/plan"
|
||||
)
|
||||
|
||||
const (
|
||||
ultradnsDefaultTTL = 198
|
||||
ultradnsCreate = "CREATE"
|
||||
ultradnsDelete = "DELETE"
|
||||
ultradnsUpdate = "UPDATE"
|
||||
sbPoolPriority = 1
|
||||
sbPoolOrder = "ROUND_ROBIN"
|
||||
rdPoolOrder = "ROUND_ROBIN"
|
||||
)
|
||||
|
||||
// global variables
|
||||
var sbPoolRunProbes = true
|
||||
var sbPoolActOnProbes = true
|
||||
var ultradnsPoolType = "rdpool"
|
||||
|
||||
//Setting custom headers for ultradns api calls
|
||||
var customHeader = []udnssdk.CustomHeader{
|
||||
udnssdk.CustomHeader {
|
||||
Key: "UltraClient",
|
||||
Value: "kube-client",
|
||||
},
|
||||
}
|
||||
|
||||
type UltraDNSProvider struct {
|
||||
client udnssdk.Client
|
||||
|
||||
domainFilter endpoint.DomainFilter
|
||||
DryRun bool
|
||||
AccountName string
|
||||
}
|
||||
|
||||
type UltraDNSChanges struct {
|
||||
Action string
|
||||
|
||||
ResourceRecordSetUltraDNS udnssdk.RRSet
|
||||
}
|
||||
|
||||
// NewUltraDNSProvider initializes a new UltraDNS DNS based provider
|
||||
func NewUltraDNSProvider(domainFilter endpoint.DomainFilter, dryRun bool) (*UltraDNSProvider, error) {
|
||||
Username, ok := os.LookupEnv("ULTRADNS_USERNAME")
|
||||
udnssdk.SetCustomHeader = customHeader
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no username found")
|
||||
}
|
||||
|
||||
Base64Password, ok := os.LookupEnv("ULTRADNS_PASSWORD")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no password found")
|
||||
}
|
||||
|
||||
// Base64 Standard Decoding
|
||||
Password, err := base64.StdEncoding.DecodeString(Base64Password)
|
||||
if err != nil {
|
||||
fmt.Printf("Error decoding string: %s ", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
BaseURL, ok := os.LookupEnv("ULTRADNS_BASEURL")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no baseurl found")
|
||||
}
|
||||
AccountName, ok := os.LookupEnv("ULTRADNS_ACCOUNTNAME")
|
||||
if !ok {
|
||||
AccountName = ""
|
||||
}
|
||||
|
||||
probeValue, ok := os.LookupEnv("ULTRADNS_ENABLE_PROBING")
|
||||
if ok {
|
||||
if (probeValue != "true") && (probeValue != "false") {
|
||||
return nil, fmt.Errorf("please set proper probe value, the values can be either true or false")
|
||||
} else {
|
||||
sbPoolRunProbes, _ = strconv.ParseBool(probeValue)
|
||||
}
|
||||
}
|
||||
|
||||
actOnProbeValue, ok := os.LookupEnv("ULTRADNS_ENABLE_ACTONPROBE")
|
||||
if ok {
|
||||
if (actOnProbeValue != "true") && (actOnProbeValue != "false") {
|
||||
return nil, fmt.Errorf("please set proper act on probe value, the values can be either true or false")
|
||||
} else {
|
||||
sbPoolActOnProbes, _ = strconv.ParseBool(actOnProbeValue)
|
||||
}
|
||||
}
|
||||
|
||||
poolValue, ok := os.LookupEnv("ULTRADNS_POOL_TYPE")
|
||||
if ok {
|
||||
if (poolValue != "sbpool") && (poolValue != "rdpool") {
|
||||
return nil, fmt.Errorf(" please set proper ULTRADNS_POOL_TYPE, supported types are sbpool or rdpool")
|
||||
}
|
||||
ultradnsPoolType = poolValue
|
||||
}
|
||||
|
||||
client, err := udnssdk.NewClient(Username, string(Password), BaseURL)
|
||||
if err != nil {
|
||||
|
||||
return nil, fmt.Errorf("Connection cannot be established")
|
||||
}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: *client,
|
||||
domainFilter: domainFilter,
|
||||
DryRun: dryRun,
|
||||
AccountName: AccountName,
|
||||
}
|
||||
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
// Zones returns list of hosted zones
|
||||
func (p *UltraDNSProvider) Zones(ctx context.Context) ([]udnssdk.Zone, error) {
|
||||
zoneKey := &udnssdk.ZoneKey{}
|
||||
if p.AccountName != "" {
|
||||
zoneKey = &udnssdk.ZoneKey{
|
||||
Zone: "",
|
||||
AccountName: p.AccountName,
|
||||
}
|
||||
}
|
||||
|
||||
zones, err := p.fetchZones(ctx, zoneKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
zones, err := p.Zones(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, zone := range zones {
|
||||
log.Infof("zones : %v", zone)
|
||||
rrsetType := ""
|
||||
ownerName := ""
|
||||
rrsetKey := udnssdk.RRSetKey{
|
||||
Zone: zone.Properties.Name,
|
||||
Type: rrsetType,
|
||||
Name: ownerName,
|
||||
}
|
||||
|
||||
if zone.Properties.ResourceRecordCount != 0 {
|
||||
records, err := p.fetchRecords(ctx, rrsetKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, r := range records {
|
||||
recordTypeArray := strings.Fields(r.RRType)
|
||||
if supportedRecordType(recordTypeArray[0]) {
|
||||
log.Infof("owner name %s", r.OwnerName)
|
||||
name := fmt.Sprintf("%s", r.OwnerName)
|
||||
|
||||
// root name is identified by the empty string and should be
|
||||
// translated to zone name for the endpoint entry.
|
||||
if r.OwnerName == "" {
|
||||
name = zone.Properties.Name
|
||||
}
|
||||
|
||||
endPointTTL := endpoint.NewEndpointWithTTL(name, recordTypeArray[0], endpoint.TTL(r.TTL), r.RData...)
|
||||
endpoints = append(endpoints, endPointTTL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
log.Infof("endpoints %v", endpoints)
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) fetchRecords(ctx context.Context, k udnssdk.RRSetKey) ([]udnssdk.RRSet, error) {
|
||||
// TODO: Sane Configuration for timeouts / retries
|
||||
maxerrs := 5
|
||||
waittime := 5 * time.Second
|
||||
|
||||
rrsets := []udnssdk.RRSet{}
|
||||
errcnt := 0
|
||||
offset := 0
|
||||
limit := 1000
|
||||
|
||||
for {
|
||||
reqRrsets, ri, res, err := p.client.RRSets.SelectWithOffsetWithLimit(k, offset, limit)
|
||||
if err != nil {
|
||||
if res != nil && res.StatusCode >= 500 {
|
||||
errcnt = errcnt + 1
|
||||
if errcnt < maxerrs {
|
||||
time.Sleep(waittime)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return rrsets, err
|
||||
}
|
||||
|
||||
for _, rrset := range reqRrsets {
|
||||
rrsets = append(rrsets, rrset)
|
||||
}
|
||||
if ri.ReturnedCount+ri.Offset >= ri.TotalCount {
|
||||
return rrsets, nil
|
||||
}
|
||||
offset = ri.ReturnedCount + ri.Offset
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) fetchZones(ctx context.Context, zoneKey *udnssdk.ZoneKey) ([]udnssdk.Zone, error) {
|
||||
// Select will list the zone rrsets, paginating through all available results
|
||||
// TODO: Sane Configuration for timeouts / retries
|
||||
maxerrs := 5
|
||||
waittime := 5 * time.Second
|
||||
|
||||
zones := []udnssdk.Zone{}
|
||||
|
||||
errcnt := 0
|
||||
offset := 0
|
||||
limit := 1000
|
||||
|
||||
for {
|
||||
reqZones, ri, res, err := p.client.Zone.SelectWithOffsetWithLimit(zoneKey, offset, limit)
|
||||
if err != nil {
|
||||
if res != nil && res.StatusCode >= 500 {
|
||||
errcnt = errcnt + 1
|
||||
if errcnt < maxerrs {
|
||||
time.Sleep(waittime)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return zones, err
|
||||
}
|
||||
|
||||
for _, zone := range reqZones {
|
||||
|
||||
if p.domainFilter.IsConfigured() {
|
||||
if p.domainFilter.Match(zone.Properties.Name) {
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
} else {
|
||||
zones = append(zones, zone)
|
||||
}
|
||||
}
|
||||
if ri.ReturnedCount+ri.Offset >= ri.TotalCount {
|
||||
return zones, nil
|
||||
}
|
||||
offset = ri.ReturnedCount + ri.Offset
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) submitChanges(ctx context.Context, changes []*UltraDNSChanges) error {
|
||||
cnameownerName := "cname"
|
||||
txtownerName := "txt"
|
||||
if len(changes) == 0 {
|
||||
log.Infof("All records are already up to date")
|
||||
return nil
|
||||
}
|
||||
|
||||
zones, err := p.Zones(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zoneChanges := seperateChangeByZone(zones, changes)
|
||||
|
||||
for zoneName, changes := range zoneChanges {
|
||||
|
||||
for _, change := range changes {
|
||||
|
||||
if change.ResourceRecordSetUltraDNS.RRType == "CNAME" {
|
||||
cnameownerName = change.ResourceRecordSetUltraDNS.OwnerName
|
||||
} else if change.ResourceRecordSetUltraDNS.RRType == "TXT" {
|
||||
txtownerName = change.ResourceRecordSetUltraDNS.OwnerName
|
||||
}
|
||||
|
||||
if cnameownerName == txtownerName {
|
||||
rrsetKey := udnssdk.RRSetKey{
|
||||
Zone: zoneName,
|
||||
Type: endpoint.RecordTypeCNAME,
|
||||
Name: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
}
|
||||
err := p.getSpecificRecord(ctx, rrsetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.DryRun != true {
|
||||
_, err = p.client.RRSets.Delete(rrsetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("The CNAME and TXT Record name cannot be same please recreate external-dns with - --txt-prefix=")
|
||||
}
|
||||
rrsetKey := udnssdk.RRSetKey{
|
||||
Zone: zoneName,
|
||||
Type: change.ResourceRecordSetUltraDNS.RRType,
|
||||
Name: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
}
|
||||
record := udnssdk.RRSet{}
|
||||
if ((change.ResourceRecordSetUltraDNS.RRType == "A" || change.ResourceRecordSetUltraDNS.RRType == "AAAA" ) && (len(change.ResourceRecordSetUltraDNS.RData) >= 2)) {
|
||||
if ultradnsPoolType == "sbpool" && change.ResourceRecordSetUltraDNS.RRType == "A" {
|
||||
sbPoolObject, _ := p.newSBPoolObjectCreation(ctx, change)
|
||||
record = udnssdk.RRSet{
|
||||
RRType: change.ResourceRecordSetUltraDNS.RRType,
|
||||
OwnerName: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
RData: change.ResourceRecordSetUltraDNS.RData,
|
||||
TTL: change.ResourceRecordSetUltraDNS.TTL,
|
||||
Profile: sbPoolObject.RawProfile(),
|
||||
}
|
||||
} else if ultradnsPoolType == "rdpool" {
|
||||
rdPoolObject, _ := p.newRDPoolObjectCreation(ctx, change)
|
||||
record = udnssdk.RRSet{
|
||||
RRType: change.ResourceRecordSetUltraDNS.RRType,
|
||||
OwnerName: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
RData: change.ResourceRecordSetUltraDNS.RData,
|
||||
TTL: change.ResourceRecordSetUltraDNS.TTL,
|
||||
Profile: rdPoolObject.RawProfile(),
|
||||
}
|
||||
}else{
|
||||
return fmt.Errorf("We do not support Multiple target AAAA records in SB Pool please contact to Neustar for further details")
|
||||
}
|
||||
}else {
|
||||
record = udnssdk.RRSet{
|
||||
RRType: change.ResourceRecordSetUltraDNS.RRType,
|
||||
OwnerName: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
RData: change.ResourceRecordSetUltraDNS.RData,
|
||||
TTL: change.ResourceRecordSetUltraDNS.TTL,
|
||||
}
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"record": record.OwnerName,
|
||||
"type": record.RRType,
|
||||
"ttl": record.TTL,
|
||||
"action": change.Action,
|
||||
"zone": zoneName,
|
||||
"profile": record.Profile,
|
||||
}).Info("Changing record.")
|
||||
|
||||
switch change.Action {
|
||||
case ultradnsCreate:
|
||||
if p.DryRun != true {
|
||||
res, err := p.client.RRSets.Create(rrsetKey, record)
|
||||
_ = res
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case ultradnsDelete:
|
||||
err := p.getSpecificRecord(ctx, rrsetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if p.DryRun != true {
|
||||
_, err = p.client.RRSets.Delete(rrsetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case ultradnsUpdate:
|
||||
err := p.getSpecificRecord(ctx, rrsetKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if p.DryRun != true {
|
||||
_, err = p.client.RRSets.Update(rrsetKey, record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error {
|
||||
combinedChanges := make([]*UltraDNSChanges, 0, len(changes.Create)+len(changes.UpdateNew)+len(changes.Delete))
|
||||
log.Infof("value of changes %v,%v,%v", changes.Create, changes.UpdateNew, changes.Delete)
|
||||
combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsCreate, changes.Create)...)
|
||||
combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsUpdate, changes.UpdateNew)...)
|
||||
combinedChanges = append(combinedChanges, newUltraDNSChanges(ultradnsDelete, changes.Delete)...)
|
||||
|
||||
return p.submitChanges(ctx, combinedChanges)
|
||||
}
|
||||
|
||||
func newUltraDNSChanges(action string, endpoints []*endpoint.Endpoint) []*UltraDNSChanges {
|
||||
changes := make([]*UltraDNSChanges, 0, len(endpoints))
|
||||
ttl := ultradnsDefaultTTL
|
||||
for _, e := range endpoints {
|
||||
|
||||
if e.RecordTTL.IsConfigured() {
|
||||
ttl = int(e.RecordTTL)
|
||||
}
|
||||
|
||||
// Adding suffix dot to the record name
|
||||
recordName := fmt.Sprintf("%s.", e.DNSName)
|
||||
change := &UltraDNSChanges{
|
||||
Action: action,
|
||||
ResourceRecordSetUltraDNS: udnssdk.RRSet{
|
||||
RRType: e.RecordType,
|
||||
OwnerName: recordName,
|
||||
RData: e.Targets,
|
||||
TTL: ttl,
|
||||
},
|
||||
}
|
||||
changes = append(changes, change)
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
func seperateChangeByZone(zones []udnssdk.Zone, changes []*UltraDNSChanges) map[string][]*UltraDNSChanges {
|
||||
change := make(map[string][]*UltraDNSChanges)
|
||||
zoneNameID := zoneIDName{}
|
||||
for _, z := range zones {
|
||||
zoneNameID.Add(z.Properties.Name, z.Properties.Name)
|
||||
change[z.Properties.Name] = []*UltraDNSChanges{}
|
||||
}
|
||||
|
||||
for _, c := range changes {
|
||||
zone, _ := zoneNameID.FindZone(c.ResourceRecordSetUltraDNS.OwnerName)
|
||||
if zone == "" {
|
||||
log.Infof("Skipping record %s because no hosted zone matching record DNS Name was detected", c.ResourceRecordSetUltraDNS.OwnerName)
|
||||
continue
|
||||
}
|
||||
change[zone] = append(change[zone], c)
|
||||
|
||||
}
|
||||
return change
|
||||
}
|
||||
|
||||
func (p *UltraDNSProvider) getSpecificRecord(ctx context.Context, rrsetKey udnssdk.RRSetKey) (err error) {
|
||||
_, err = p.client.RRSets.Select(rrsetKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("no record was found for %v", rrsetKey)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Creation of SBPoolObject
|
||||
func (p *UltraDNSProvider) newSBPoolObjectCreation(ctx context.Context, change *UltraDNSChanges) (sbPool udnssdk.SBPoolProfile, err error) {
|
||||
|
||||
sbpoolRDataList := []udnssdk.SBRDataInfo{}
|
||||
for _, _ = range change.ResourceRecordSetUltraDNS.RData {
|
||||
|
||||
rrdataInfo := udnssdk.SBRDataInfo{
|
||||
RunProbes: sbPoolRunProbes,
|
||||
Priority: sbPoolPriority,
|
||||
State: "NORMAL",
|
||||
Threshold: 1,
|
||||
Weight: nil,
|
||||
}
|
||||
sbpoolRDataList = append(sbpoolRDataList, rrdataInfo)
|
||||
}
|
||||
sbPoolObject := udnssdk.SBPoolProfile{
|
||||
Context: udnssdk.SBPoolSchema,
|
||||
Order: sbPoolOrder,
|
||||
Description: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
MaxActive: len(change.ResourceRecordSetUltraDNS.RData),
|
||||
MaxServed: len(change.ResourceRecordSetUltraDNS.RData),
|
||||
RDataInfo: sbpoolRDataList,
|
||||
RunProbes: sbPoolRunProbes,
|
||||
ActOnProbes: sbPoolActOnProbes,
|
||||
}
|
||||
return sbPoolObject, nil
|
||||
}
|
||||
|
||||
//Creation of RDPoolObject
|
||||
func (p *UltraDNSProvider) newRDPoolObjectCreation(ctx context.Context, change *UltraDNSChanges) (rdPool udnssdk.RDPoolProfile, err error) {
|
||||
|
||||
rdPoolObject := udnssdk.RDPoolProfile{
|
||||
Context: udnssdk.RDPoolSchema,
|
||||
Order: rdPoolOrder,
|
||||
Description: change.ResourceRecordSetUltraDNS.OwnerName,
|
||||
}
|
||||
return rdPoolObject, nil
|
||||
}
|
686
provider/ultradns_test.go
Normal file
686
provider/ultradns_test.go
Normal file
@ -0,0 +1,686 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
_ "strings"
|
||||
"testing"
|
||||
|
||||
udnssdk "github.com/ultradns/ultradns-sdk-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
"sigs.k8s.io/external-dns/plan"
|
||||
)
|
||||
|
||||
type mockUltraDNSZone struct {
|
||||
client *udnssdk.Client
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSZone) SelectWithOffsetWithLimit(k *udnssdk.ZoneKey, offset int, limit int) (zones []udnssdk.Zone, ResultInfo udnssdk.ResultInfo, resp *http.Response, err error) {
|
||||
zones = []udnssdk.Zone{}
|
||||
zone := udnssdk.Zone{}
|
||||
zoneJson := `
|
||||
{
|
||||
"properties": {
|
||||
"name":"test-ultradns-provider.com.",
|
||||
"accountName":"teamrest",
|
||||
"type":"PRIMARY",
|
||||
"dnssecStatus":"UNSIGNED",
|
||||
"status":"ACTIVE",
|
||||
"owner":"teamrest",
|
||||
"resourceRecordCount":7,
|
||||
"lastModifiedDateTime":""
|
||||
}
|
||||
}`
|
||||
if err := json.Unmarshal([]byte(zoneJson), &zone); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
zones = append(zones, zone)
|
||||
return zones, udnssdk.ResultInfo{}, nil, nil
|
||||
}
|
||||
|
||||
type mockUltraDNSRecord struct {
|
||||
client *udnssdk.Client
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) Create(k udnssdk.RRSetKey, rrset udnssdk.RRSet) (*http.Response, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) Select(k udnssdk.RRSetKey) ([]udnssdk.RRSet, error) {
|
||||
return []udnssdk.RRSet{{
|
||||
OwnerName: "test-ultradns-provider.com.",
|
||||
RRType: endpoint.RecordTypeA,
|
||||
RData: []string{"1.1.1.1"},
|
||||
TTL: 86400,
|
||||
}}, nil
|
||||
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) SelectWithOffset(k udnssdk.RRSetKey, offset int) ([]udnssdk.RRSet, udnssdk.ResultInfo, *http.Response, error) {
|
||||
return nil, udnssdk.ResultInfo{}, nil, nil
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) Update(udnssdk.RRSetKey, udnssdk.RRSet) (*http.Response, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) Delete(k udnssdk.RRSetKey) (*http.Response, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockUltraDNSRecord) SelectWithOffsetWithLimit(k udnssdk.RRSetKey, offset int, limit int) (rrsets []udnssdk.RRSet, ResultInfo udnssdk.ResultInfo, resp *http.Response, err error) {
|
||||
return []udnssdk.RRSet{{
|
||||
OwnerName: "test-ultradns-provider.com.",
|
||||
RRType: endpoint.RecordTypeA,
|
||||
RData: []string{"1.1.1.1"},
|
||||
TTL: 86400,
|
||||
}}, udnssdk.ResultInfo{}, nil, nil
|
||||
}
|
||||
|
||||
// NewUltraDNSProvider Test scenario
|
||||
func TestNewUltraDNSProvider(t *testing.T) {
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.Nil(t,err)
|
||||
|
||||
_ = os.Unsetenv("ULTRADNS_PASSWORD")
|
||||
_ = os.Unsetenv("ULTRADNS_USERNAME")
|
||||
_ = os.Unsetenv("ULTRADNS_BASEURL")
|
||||
_ = os.Unsetenv("ULTRADNS_ACCOUNTNAME")
|
||||
_, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Expected to fail %s","formatted")
|
||||
}
|
||||
|
||||
//zones function test scenario
|
||||
func TestUltraDNSProvider_Zones(t *testing.T) {
|
||||
mocked := mockUltraDNSZone{}
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
Zone: &mocked,
|
||||
},
|
||||
}
|
||||
|
||||
zoneKey := &udnssdk.ZoneKey{
|
||||
Zone: "",
|
||||
AccountName: "teamrest",
|
||||
}
|
||||
|
||||
expected, _, _, err := provider.client.Zone.SelectWithOffsetWithLimit(zoneKey, 0, 1000)
|
||||
assert.Nil(t,err)
|
||||
zones, err := provider.Zones(context.Background())
|
||||
assert.Nil(t,err)
|
||||
assert.Equal(t,reflect.DeepEqual(expected, zones),true)
|
||||
}
|
||||
|
||||
//Records function test case
|
||||
func TestUltraDNSProvider_Records(t *testing.T) {
|
||||
mocked := mockUltraDNSRecord{}
|
||||
mockedDomain := mockUltraDNSZone{}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
rrsetKey := udnssdk.RRSetKey{}
|
||||
expected, _, _, err := provider.client.RRSets.SelectWithOffsetWithLimit(rrsetKey, 0, 1000)
|
||||
records, err := provider.Records(context.Background())
|
||||
assert.Nil(t,err)
|
||||
for _, v := range records {
|
||||
assert.Equal(t, fmt.Sprintf("%s.", v.DNSName), expected[0].OwnerName)
|
||||
assert.Equal(t, v.RecordType, expected[0].RRType)
|
||||
assert.Equal(t, int(v.RecordTTL), expected[0].TTL)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//ApplyChanges function testcase
|
||||
func TestUltraDNSProvider_ApplyChanges(t *testing.T) {
|
||||
changes := &plan.Changes{}
|
||||
mocked := mockUltraDNSRecord{nil}
|
||||
mockedDomain := mockUltraDNSZone{nil}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A"},
|
||||
{DNSName: "ttl.test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", RecordTTL: 100},
|
||||
}
|
||||
changes.Create = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.2"}, RecordType: "A"}}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2", "1.1.2.3", "1.1.2.4"}, RecordType: "A", RecordTTL: 100}}
|
||||
changes.Delete = []*endpoint.Endpoint{{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.2.2", "1.1.2.3", "1.1.2.4"}, RecordType: "A", RecordTTL: 100}}
|
||||
changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A", RecordTTL: 100}}
|
||||
err := provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nilf(t,err,"Should not fail %s","formatted")
|
||||
}
|
||||
|
||||
// Testing function getSpecificRecord
|
||||
func TestUltraDNSProvider_getSpecificRecord(t *testing.T) {
|
||||
mocked := mockUltraDNSRecord{nil}
|
||||
mockedDomain := mockUltraDNSZone{nil}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
|
||||
recordSetKey := udnssdk.RRSetKey{
|
||||
Zone: "test-ultradns-provider.com.",
|
||||
Type: "A",
|
||||
Name: "teamrest",
|
||||
}
|
||||
err := provider.getSpecificRecord(context.Background(), recordSetKey)
|
||||
assert.Nil(t,err)
|
||||
}
|
||||
|
||||
//Fail case scenario testing where CNAME and TXT Record name are same
|
||||
func TestUltraDNSProvider_ApplyChangesCNAME(t *testing.T) {
|
||||
changes := &plan.Changes{}
|
||||
mocked := mockUltraDNSRecord{nil}
|
||||
mockedDomain := mockUltraDNSZone{nil}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "CNAME"},
|
||||
{DNSName: "test-ultradns-provider.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "TXT"},
|
||||
}
|
||||
|
||||
err := provider.ApplyChanges(context.Background(), changes)
|
||||
assert.NotNil(t,err)
|
||||
}
|
||||
|
||||
// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be avaialble "kubernetes-ultradns-provider-test.com"
|
||||
func TestUltraDNSProvider_ApplyChanges_Integration(t *testing.T) {
|
||||
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
|
||||
providerUltradns, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1"}, RecordType: "A"},
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, RecordType: "AAAA", RecordTTL: 100},
|
||||
}
|
||||
|
||||
err = providerUltradns.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
|
||||
rrsetKey := udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "kubernetes-ultradns-provider-test.com.",
|
||||
Type: "A",
|
||||
}
|
||||
|
||||
rrsets, _ := providerUltradns.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData[0], "1.1.1.1")
|
||||
|
||||
rrsetKey = udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "ttl.kubernetes-ultradns-provider-test.com.",
|
||||
Type: "AAAA",
|
||||
}
|
||||
|
||||
rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData[0], "2001:db8:85a3:0:0:8a2e:370:7334")
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{
|
||||
{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100},
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100}}
|
||||
err = providerUltradns.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
|
||||
rrsetKey = udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "kubernetes-ultradns-provider-test.com.",
|
||||
Type: "A",
|
||||
}
|
||||
|
||||
rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData[0], "1.1.2.2")
|
||||
|
||||
rrsetKey = udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "ttl.kubernetes-ultradns-provider-test.com.",
|
||||
Type: "AAAA",
|
||||
}
|
||||
|
||||
rrsets, _ = providerUltradns.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData[0], "2001:db8:85a3:0:0:8a2e:370:7335")
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.Delete = []*endpoint.Endpoint{
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100},
|
||||
{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}}
|
||||
|
||||
err = providerUltradns.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
|
||||
resp, _ := providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
|
||||
resp, _ = providerUltradns.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// This will work if you would set the environment variables such as "ULTRADNS_INTEGRATION" and zone should be avaialble "kubernetes-ultradns-provider-test.com" for multiple target
|
||||
func TestUltraDNSProvider_ApplyChanges_MultipleTarget_integeration(t *testing.T) {
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
|
||||
provider, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.1.2.2"}, RecordType: "A"}}
|
||||
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
|
||||
rrsetKey := udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "kubernetes-ultradns-provider-test.com.",
|
||||
Type: "A",
|
||||
}
|
||||
|
||||
rrsets, _ := provider.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData, []string{"1.1.1.1", "1.1.2.2"})
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}}
|
||||
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
|
||||
rrsetKey = udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "kubernetes-ultradns-provider-test.com.",
|
||||
Type: "A",
|
||||
}
|
||||
|
||||
rrsets, _ = provider.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData, []string{"1.1.2.2", "192.168.0.24", "1.2.3.4"})
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2"}, RecordType: "A", RecordTTL: 100}}
|
||||
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
|
||||
assert.Nil(t,err)
|
||||
|
||||
rrsetKey = udnssdk.RRSetKey{
|
||||
Zone: "kubernetes-ultradns-provider-test.com.",
|
||||
Name: "kubernetes-ultradns-provider-test.com.",
|
||||
Type: "A",
|
||||
}
|
||||
|
||||
rrsets, _ = provider.client.RRSets.Select(rrsetKey)
|
||||
assert.Equal(t, rrsets[0].RData, []string{"1.1.2.2"})
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.Delete = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A"}}
|
||||
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
|
||||
assert.Nil(t,err)
|
||||
|
||||
resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Test case to check sbpool creation
|
||||
func TestUltraDNSProvider_newSBPoolObjectCreation(t *testing.T) {
|
||||
mocked := mockUltraDNSRecord{nil}
|
||||
mockedDomain := mockUltraDNSZone{nil}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
sbpoolRDataList := []udnssdk.SBRDataInfo{}
|
||||
changes := &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com.", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A", RecordTTL: 100}}
|
||||
changesList := &UltraDNSChanges{
|
||||
Action: "UPDATE",
|
||||
ResourceRecordSetUltraDNS: udnssdk.RRSet{
|
||||
RRType: "A",
|
||||
OwnerName: "kubernetes-ultradns-provider-test.com.",
|
||||
RData: []string{"1.1.2.2", "192.168.0.24"},
|
||||
TTL: 100,
|
||||
},
|
||||
}
|
||||
|
||||
for _, _ = range changesList.ResourceRecordSetUltraDNS.RData {
|
||||
|
||||
rrdataInfo := udnssdk.SBRDataInfo{
|
||||
RunProbes: true,
|
||||
Priority: 1,
|
||||
State: "NORMAL",
|
||||
Threshold: 1,
|
||||
Weight: nil,
|
||||
}
|
||||
sbpoolRDataList = append(sbpoolRDataList, rrdataInfo)
|
||||
}
|
||||
sbPoolObject := udnssdk.SBPoolProfile{
|
||||
Context: udnssdk.SBPoolSchema,
|
||||
Order: "ROUND_ROBIN",
|
||||
Description: "kubernetes-ultradns-provider-test.com.",
|
||||
MaxActive: 2,
|
||||
MaxServed: 2,
|
||||
RDataInfo: sbpoolRDataList,
|
||||
RunProbes: true,
|
||||
ActOnProbes: true,
|
||||
}
|
||||
|
||||
actualSBPoolObject, _ := provider.newSBPoolObjectCreation(context.Background(), changesList)
|
||||
assert.Equal(t, sbPoolObject, actualSBPoolObject)
|
||||
|
||||
}
|
||||
|
||||
//Testcase to check fail scenario for multiple AAAA targets
|
||||
func TestUltraDNSProvider_MultipleTargetAAAA(t *testing.T) {
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool")
|
||||
|
||||
provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100},
|
||||
}
|
||||
err := provider.ApplyChanges(context.Background(), changes)
|
||||
assert.NotNilf(t,err,"We wanted it to fail since multiple AAAA targets are not allowed %s","formatted")
|
||||
|
||||
resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
_ = os.Unsetenv("ULTRADNS_POOL_TYPE")
|
||||
}
|
||||
}
|
||||
|
||||
//Testcase to check fail scenario for multiple AAAA targets
|
||||
func TestUltraDNSProvider_MultipleTargetAAAARDPool(t *testing.T) {
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool")
|
||||
provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA", RecordTTL: 100},
|
||||
}
|
||||
err := provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nilf(t,err," multiple AAAA targets are allowed when pool is RDPool %s","formatted")
|
||||
|
||||
resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/AAAA/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "200 OK")
|
||||
|
||||
changes = &plan.Changes{}
|
||||
changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"}, RecordType: "AAAA"}}
|
||||
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
|
||||
assert.Nil(t,err)
|
||||
|
||||
resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Test case to check multiple CNAME targets.
|
||||
func TestUltraDNSProvider_MultipleTargetCNAME(t *testing.T) {
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
provider, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
|
||||
changes.Create = []*endpoint.Endpoint{
|
||||
{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"nginx.loadbalancer.com.", "nginx1.loadbalancer.com."}, RecordType: "CNAME", RecordTTL: 100},
|
||||
}
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
|
||||
assert.NotNilf(t,err,"We wanted it to fail since multiple CNAME targets are not allowed %s","formatted")
|
||||
|
||||
|
||||
resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/CNAME/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
}
|
||||
}
|
||||
|
||||
//Testing creation of RD Pool
|
||||
func TestUltraDNSProvider_newRDPoolObjectCreation(t *testing.T) {
|
||||
mocked := mockUltraDNSRecord{nil}
|
||||
mockedDomain := mockUltraDNSZone{nil}
|
||||
|
||||
provider := &UltraDNSProvider{
|
||||
client: udnssdk.Client{
|
||||
RRSets: &mocked,
|
||||
Zone: &mockedDomain,
|
||||
},
|
||||
}
|
||||
changes := &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "kubernetes-ultradns-provider-test.com.", Targets: endpoint.Targets{"1.1.2.2", "192.168.0.24"}, RecordType: "A", RecordTTL: 100}}
|
||||
changesList := &UltraDNSChanges{
|
||||
Action: "UPDATE",
|
||||
ResourceRecordSetUltraDNS: udnssdk.RRSet{
|
||||
RRType: "A",
|
||||
OwnerName: "kubernetes-ultradns-provider-test.com.",
|
||||
RData: []string{"1.1.2.2", "192.168.0.24"},
|
||||
TTL: 100,
|
||||
},
|
||||
}
|
||||
rdPoolObject := udnssdk.RDPoolProfile{
|
||||
Context: udnssdk.RDPoolSchema,
|
||||
Order: "ROUND_ROBIN",
|
||||
Description: "kubernetes-ultradns-provider-test.com.",
|
||||
}
|
||||
|
||||
actualRDPoolObject, _ := provider.newRDPoolObjectCreation(context.Background(), changesList)
|
||||
assert.Equal(t, rdPoolObject, actualRDPoolObject)
|
||||
|
||||
}
|
||||
|
||||
//Testing Failure scenarios over NewUltraDNS Provider
|
||||
func TestNewUltraDNSProvider_FailCases(t *testing.T) {
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE", "xyz")
|
||||
_, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Pool Type other than given type not working %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_ENABLE_PROBING", "adefg")
|
||||
_, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Probe value other than given values not working %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "adefg")
|
||||
_, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"ActOnProbe value other than given values not working %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Unsetenv("ULTRADNS_PASSWORD")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Expected to give error if password is not set %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Unsetenv("ULTRADNS_BASEURL")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_, err = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Expected to give error if baseurl is not set %s","formatted")
|
||||
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Unsetenv("ULTRADNS_ACCOUNTNAME")
|
||||
_ = os.Unsetenv("ULTRADNS_ENABLE_ACTONPROBE")
|
||||
_ = os.Unsetenv("ULTRADNS_ENABLE_PROBING")
|
||||
_ = os.Unsetenv("ULTRADNS_POOL_TYPE")
|
||||
_, accounterr := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.Nil(t,accounterr)
|
||||
|
||||
}
|
||||
|
||||
// Testing success scenarios for newly introduced environment variables
|
||||
func TestNewUltraDNSProvider_NewEnvVariableSuccessCases(t *testing.T) {
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE", "rdpool")
|
||||
_, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.Nilf(t,err,"Pool Type not working in proper scenario %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_ENABLE_PROBING", "false")
|
||||
_, err1 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.Nilf(t,err1,"Probe given value is not working %s","formatted")
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true")
|
||||
_, err2 := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.Nilf(t,err2,"ActOnProbe given value is not working %s","formatted")
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Base64 Bad string decoding scenario
|
||||
func TestNewUltraDNSProvider_Base64DecodeFailcase(t *testing.T) {
|
||||
|
||||
_ = os.Setenv("ULTRADNS_USERNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_PASSWORD", "12345")
|
||||
_ = os.Setenv("ULTRADNS_BASEURL", "")
|
||||
_ = os.Setenv("ULTRADNS_ACCOUNTNAME", "")
|
||||
_ = os.Setenv("ULTRADNS_ENABLE_ACTONPROBE", "true")
|
||||
_, err := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"test-ultradns-provider.com"}), true)
|
||||
assert.NotNilf(t,err,"Base64 decode should fail in this case %s","formatted")
|
||||
|
||||
}
|
||||
|
||||
func TestUltraDNSProvider_PoolConversionCase(t *testing.T){
|
||||
|
||||
_, ok := os.LookupEnv("ULTRADNS_INTEGRATION")
|
||||
if !ok {
|
||||
log.Printf("Skipping test")
|
||||
|
||||
} else {
|
||||
//Creating SBPool Record
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool")
|
||||
provider, _ := NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes := &plan.Changes{}
|
||||
changes.Create = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1", "1.2.3.4"}, RecordType: "A", RecordTTL: 100}}
|
||||
err := provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nilf(t,err," multiple A record creation with SBPool %s","formatted")
|
||||
|
||||
resp, _ := provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "200 OK")
|
||||
|
||||
//Coverting to RD Pool
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE","rdpool")
|
||||
provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes = &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.5"}, RecordType: "A"}}
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "200 OK")
|
||||
|
||||
|
||||
//Coverting back to SB Pool
|
||||
_ = os.Setenv("ULTRADNS_POOL_TYPE","sbpool")
|
||||
provider, _ = NewUltraDNSProvider(endpoint.NewDomainFilter([]string{"kubernetes-ultradns-provider-test.com"}), false)
|
||||
changes = &plan.Changes{}
|
||||
changes.UpdateNew = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}}
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/ttl.kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "200 OK")
|
||||
|
||||
//Deleting Record
|
||||
changes = &plan.Changes{}
|
||||
changes.Delete = []*endpoint.Endpoint{{DNSName: "ttl.kubernetes-ultradns-provider-test.com", Targets: endpoint.Targets{"1.1.1.1","1.2.3.4"}, RecordType: "A"}}
|
||||
err = provider.ApplyChanges(context.Background(), changes)
|
||||
assert.Nil(t,err)
|
||||
resp, _ = provider.client.Do("GET", "zones/kubernetes-ultradns-provider-test.com./rrsets/A/kubernetes-ultradns-provider-test.com.", nil, udnssdk.RRSetListDTO{})
|
||||
assert.Equal(t, resp.Status, "404 Not Found")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user