mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 17:46:57 +02:00
chore(code): improve some tests + re-order sources flags CLI (#5288)
* fix(plan): always use managed records * robust random port in test * use defaultconfig for managed-record-types * be explicit about static variable * fix wait * re-order flags related to sources + dynamic managedrecordtype help * fix flag doc
This commit is contained in:
parent
5dcf2f0f54
commit
3c93bcb076
@ -18,6 +18,7 @@ package controller
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -29,10 +30,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
"sigs.k8s.io/external-dns/pkg/apis/externaldns"
|
||||
"sigs.k8s.io/external-dns/plan"
|
||||
@ -219,18 +219,45 @@ func TestHandleSigterm(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeMetrics(t *testing.T) {
|
||||
l, _ := net.Listen("tcp", ":0")
|
||||
_ = l.Close()
|
||||
_, port, _ := net.SplitHostPort(l.Addr().String())
|
||||
func getRandomPort() (int, error) {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
go serveMetrics(fmt.Sprintf(":%s", port))
|
||||
resp, err := http.Get(fmt.Sprintf("http://localhost:%s", port) + "/healthz")
|
||||
assert.NoError(t, err)
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().(*net.TCPAddr).Port, nil
|
||||
}
|
||||
|
||||
func TestServeMetrics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
port, err := getRandomPort()
|
||||
require.NoError(t, err)
|
||||
addresse := fmt.Sprintf("localhost:%d", port)
|
||||
|
||||
go serveMetrics(fmt.Sprintf(":%d", port))
|
||||
|
||||
// Wait for the TCP socket to be ready
|
||||
require.Eventually(t, func() bool {
|
||||
conn, err := net.Dial("tcp", addresse)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_ = conn.Close()
|
||||
return true
|
||||
}, 1*time.Second, 5*time.Millisecond, "server not ready with port open in time")
|
||||
|
||||
resp, err := http.Get(fmt.Sprintf("http://%s/healthz", addresse))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
resp, err = http.Get(fmt.Sprintf("http://localhost:%s", port) + "/metrics")
|
||||
assert.NoError(t, err)
|
||||
resp, err = http.Get(fmt.Sprintf("http://%s/metrics", addresse))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
|
||||
@ -308,7 +335,6 @@ func (m *MockProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error
|
||||
}
|
||||
|
||||
func (p *MockProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -17,40 +17,40 @@
|
||||
| `--cf-password=""` | The password to log into the cloud foundry API |
|
||||
| `--gloo-namespace=gloo-system` | The Gloo Proxy namespace; specify multiple times for multiple namespaces. (default: gloo-system) |
|
||||
| `--skipper-routegroup-groupversion="zalando.org/v1"` | The resource version for skipper routegroup |
|
||||
| `--source=source` | The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, f5-transportserver, traefik-proxy) |
|
||||
| `--openshift-router-name=OPENSHIFT-ROUTER-NAME` | if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record. |
|
||||
| `--namespace=""` | Limit resources queried for endpoints to a specific namespace (default: all namespaces) |
|
||||
| `--annotation-filter=""` | Filter resources queried for endpoints by annotation, using label selector semantics |
|
||||
| `--label-filter=""` | Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, service and ambassador-host |
|
||||
| `--ingress-class=INGRESS-CLASS` | Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class) |
|
||||
| `--fqdn-template=""` | A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN. |
|
||||
| `--[no-]combine-fqdn-annotation` | Combine FQDN template and Annotations instead of overwriting |
|
||||
| `--[no-]ignore-hostname-annotation` | Ignore hostname annotation when generating DNS names, valid only when --fqdn-template is set (default: false) |
|
||||
| `--[no-]ignore-non-host-network-pods` | Ignore pods not running on host network when using pod source (default: true) |
|
||||
| `--[no-]ignore-ingress-tls-spec` | Ignore the spec.tls section in Ingress resources (default: false) |
|
||||
| `--gateway-name=GATEWAY-NAME` | Limit Gateways of Route endpoints to a specific name (default: all names) |
|
||||
| `--gateway-namespace=GATEWAY-NAMESPACE` | Limit Gateways of Route endpoints to a specific namespace (default: all namespaces) |
|
||||
| `--gateway-label-filter=GATEWAY-LABEL-FILTER` | Filter Gateways of Route endpoints via label selector (default: all gateways) |
|
||||
| `--compatibility=` | Process annotation semantics from legacy implementations (optional, options: mate, molecule, kops-dns-controller) |
|
||||
| `--[no-]ignore-ingress-rules-spec` | Ignore the spec.rules section in Ingress resources (default: false) |
|
||||
| `--pod-source-domain=""` | Domain to use for pods records (optional) |
|
||||
| `--[no-]publish-internal-services` | Allow external-dns to publish DNS records for ClusterIP services (optional) |
|
||||
| `--[no-]publish-host-ip` | Allow external-dns to publish host-ip for headless services (optional) |
|
||||
| `--[no-]always-publish-not-ready-addresses` | Always publish also not ready addresses for headless services (optional) |
|
||||
| `--annotation-filter=""` | Filter resources queried for endpoints by annotation, using label selector semantics |
|
||||
| `--[no-]combine-fqdn-annotation` | Combine FQDN template and Annotations instead of overwriting |
|
||||
| `--compatibility=` | Process annotation semantics from legacy implementations (optional, options: mate, molecule, kops-dns-controller) |
|
||||
| `--connector-source-server="localhost:8080"` | The server to connect for connector source, valid only when using connector source |
|
||||
| `--crd-source-apiversion="externaldns.k8s.io/v1alpha1"` | API version of the CRD for crd source, e.g. `externaldns.k8s.io/v1alpha1`, valid only when using crd source |
|
||||
| `--crd-source-kind="DNSEndpoint"` | Kind of the CRD for the crd source in API group and version specified by crd-source-apiversion |
|
||||
| `--service-type-filter=SERVICE-TYPE-FILTER` | The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName) |
|
||||
| `--managed-record-types=A...` | Record types to manage; specify multiple times to include many; (default: A, AAAA, CNAME) (supported records: A, AAAA, CNAME, NS, SRV, TXT) |
|
||||
| `--exclude-record-types=EXCLUDE-RECORD-TYPES` | Record types to exclude from management; specify multiple times to exclude many; (optional) |
|
||||
| `--default-targets=DEFAULT-TARGETS` | Set globally default host/IP that will apply as a target instead of source addresses. Specify multiple times for multiple targets (optional) |
|
||||
| `--target-net-filter=TARGET-NET-FILTER` | Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional) |
|
||||
| `--exclude-record-types=EXCLUDE-RECORD-TYPES` | Record types to exclude from management; specify multiple times to exclude many; (optional) |
|
||||
| `--exclude-target-net=EXCLUDE-TARGET-NET` | Exclude target 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 |
|
||||
| `--nat64-networks=NAT64-NETWORKS` | Adding an A record for each AAAA record in NAT64-enabled networks; specify multiple times for multiple possible nets (optional) |
|
||||
| `--[no-]exclude-unschedulable` | Exclude nodes that are considered unschedulable (default: true) |
|
||||
| `--[no-]expose-internal-ipv6` | When using the node source, expose internal IPv6 addresses (optional). Default is true. |
|
||||
| `--fqdn-template=""` | A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN. |
|
||||
| `--gateway-label-filter=GATEWAY-LABEL-FILTER` | Filter Gateways of Route endpoints via label selector (default: all gateways) |
|
||||
| `--gateway-name=GATEWAY-NAME` | Limit Gateways of Route endpoints to a specific name (default: all names) |
|
||||
| `--gateway-namespace=GATEWAY-NAMESPACE` | Limit Gateways of Route endpoints to a specific namespace (default: all namespaces) |
|
||||
| `--[no-]ignore-hostname-annotation` | Ignore hostname annotation when generating DNS names, valid only when --fqdn-template is set (default: false) |
|
||||
| `--[no-]ignore-ingress-rules-spec` | Ignore the spec.rules section in Ingress resources (default: false) |
|
||||
| `--[no-]ignore-ingress-tls-spec` | Ignore the spec.tls section in Ingress resources (default: false) |
|
||||
| `--[no-]ignore-non-host-network-pods` | Ignore pods not running on host network when using pod source (default: true) |
|
||||
| `--ingress-class=INGRESS-CLASS` | Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class) |
|
||||
| `--label-filter=""` | Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, service and ambassador-host |
|
||||
| `--managed-record-types=A...` | Record types to manage; specify multiple times to include many; (default: A,AAAA,CNAME) (supported records: A, AAAA, CNAME, NS, SRV, TXT) |
|
||||
| `--namespace=""` | Limit resources queried for endpoints to a specific namespace (default: all namespaces) |
|
||||
| `--nat64-networks=NAT64-NETWORKS` | Adding an A record for each AAAA record in NAT64-enabled networks; specify multiple times for multiple possible nets (optional) |
|
||||
| `--openshift-router-name=OPENSHIFT-ROUTER-NAME` | if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record. |
|
||||
| `--pod-source-domain=""` | Domain to use for pods records (optional) |
|
||||
| `--[no-]publish-host-ip` | Allow external-dns to publish host-ip for headless services (optional) |
|
||||
| `--[no-]publish-internal-services` | Allow external-dns to publish DNS records for ClusterIP services (optional) |
|
||||
| `--service-type-filter=SERVICE-TYPE-FILTER` | The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName) |
|
||||
| `--source=source` | The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, f5-transportserver, traefik-proxy) |
|
||||
| `--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, ibmcloud, inmemory, linode, ns1, oci, ovh, pdns, pihole, plural, rfc2136, scaleway, skydns, tencentcloud, transip, ultradns, 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) |
|
||||
|
@ -217,167 +217,168 @@ type Config struct {
|
||||
}
|
||||
|
||||
var defaultConfig = &Config{
|
||||
APIServerURL: "",
|
||||
KubeConfig: "",
|
||||
RequestTimeout: time.Second * 30,
|
||||
DefaultTargets: []string{},
|
||||
GlooNamespaces: []string{"gloo-system"},
|
||||
SkipperRouteGroupVersion: "zalando.org/v1",
|
||||
Sources: nil,
|
||||
Namespace: "",
|
||||
AnnotationFilter: "",
|
||||
LabelFilter: labels.Everything().String(),
|
||||
IngressClassNames: nil,
|
||||
FQDNTemplate: "",
|
||||
CombineFQDNAndAnnotation: false,
|
||||
IgnoreHostnameAnnotation: false,
|
||||
IgnoreIngressTLSSpec: false,
|
||||
IgnoreIngressRulesSpec: false,
|
||||
GatewayName: "",
|
||||
GatewayNamespace: "",
|
||||
GatewayLabelFilter: "",
|
||||
Compatibility: "",
|
||||
PublishInternal: false,
|
||||
PublishHostIP: false,
|
||||
ExposeInternalIPV6: true,
|
||||
ConnectorSourceServer: "localhost:8080",
|
||||
Provider: "",
|
||||
ProviderCacheTime: 0,
|
||||
GoogleProject: "",
|
||||
GoogleBatchChangeSize: 1000,
|
||||
GoogleBatchChangeInterval: time.Second,
|
||||
GoogleZoneVisibility: "",
|
||||
DomainFilter: []string{},
|
||||
ZoneIDFilter: []string{},
|
||||
ExcludeDomains: []string{},
|
||||
RegexDomainFilter: regexp.MustCompile(""),
|
||||
RegexDomainExclusion: regexp.MustCompile(""),
|
||||
TargetNetFilter: []string{},
|
||||
ExcludeTargetNets: []string{},
|
||||
AkamaiAccessToken: "",
|
||||
AkamaiClientSecret: "",
|
||||
AkamaiClientToken: "",
|
||||
AkamaiEdgercPath: "",
|
||||
AkamaiEdgercSection: "",
|
||||
AkamaiServiceConsumerDomain: "",
|
||||
AlibabaCloudConfigFile: "/etc/kubernetes/alibaba-cloud.json",
|
||||
AWSZoneType: "",
|
||||
AWSZoneTagFilter: []string{},
|
||||
AWSZoneMatchParent: false,
|
||||
AnnotationFilter: "",
|
||||
APIServerURL: "",
|
||||
AWSAPIRetries: 3,
|
||||
AWSAssumeRole: "",
|
||||
AWSAssumeRoleExternalID: "",
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSBatchChangeSize: 1000,
|
||||
AWSBatchChangeSizeBytes: 32000,
|
||||
AWSBatchChangeSizeValues: 1000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSAPIRetries: 3,
|
||||
AWSPreferCNAME: false,
|
||||
AWSZoneCacheDuration: 0 * time.Second,
|
||||
AWSSDServiceCleanup: false,
|
||||
AWSSDCreateTag: map[string]string{},
|
||||
AWSDynamoDBRegion: "",
|
||||
AWSDynamoDBTable: "external-dns",
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSPreferCNAME: false,
|
||||
AWSSDCreateTag: map[string]string{},
|
||||
AWSSDServiceCleanup: false,
|
||||
AWSZoneCacheDuration: 0 * time.Second,
|
||||
AWSZoneMatchParent: false,
|
||||
AWSZoneTagFilter: []string{},
|
||||
AWSZoneType: "",
|
||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||
AzureResourceGroup: "",
|
||||
AzureSubscriptionID: "",
|
||||
AzureZonesCacheDuration: 0 * time.Second,
|
||||
CloudflareProxied: false,
|
||||
CFAPIEndpoint: "",
|
||||
CFPassword: "",
|
||||
CFUsername: "",
|
||||
CloudflareCustomHostnamesCertificateAuthority: "google",
|
||||
CloudflareCustomHostnames: false,
|
||||
CloudflareCustomHostnamesMinTLSVersion: "1.0",
|
||||
CloudflareCustomHostnamesCertificateAuthority: "google",
|
||||
CloudflareDNSRecordsPerPage: 100,
|
||||
CloudflareProxied: false,
|
||||
CloudflareRegionKey: "earth",
|
||||
|
||||
CombineFQDNAndAnnotation: false,
|
||||
Compatibility: "",
|
||||
ConnectorSourceServer: "localhost:8080",
|
||||
CoreDNSPrefix: "/skydns/",
|
||||
AkamaiServiceConsumerDomain: "",
|
||||
AkamaiClientToken: "",
|
||||
AkamaiClientSecret: "",
|
||||
AkamaiAccessToken: "",
|
||||
AkamaiEdgercSection: "",
|
||||
AkamaiEdgercPath: "",
|
||||
OCIConfigFile: "/etc/kubernetes/oci.yaml",
|
||||
OCIZoneScope: "GLOBAL",
|
||||
OCIZoneCacheDuration: 0 * time.Second,
|
||||
InMemoryZones: []string{},
|
||||
OVHEndpoint: "ovh-eu",
|
||||
OVHApiRateLimit: 20,
|
||||
OVHEnableCNAMERelative: false,
|
||||
PDNSServer: "http://localhost:8081",
|
||||
PDNSServerID: "localhost",
|
||||
PDNSAPIKey: "",
|
||||
PDNSSkipTLSVerify: false,
|
||||
PodSourceDomain: "",
|
||||
TLSCA: "",
|
||||
TLSClientCert: "",
|
||||
TLSClientCertKey: "",
|
||||
Policy: "sync",
|
||||
Registry: "txt",
|
||||
TXTOwnerID: "default",
|
||||
TXTPrefix: "",
|
||||
TXTSuffix: "",
|
||||
TXTCacheInterval: 0,
|
||||
TXTWildcardReplacement: "",
|
||||
MinEventSyncInterval: 5 * time.Second,
|
||||
TXTEncryptEnabled: false,
|
||||
TXTEncryptAESKey: "",
|
||||
TXTNewFormatOnly: false,
|
||||
Interval: time.Minute,
|
||||
Once: false,
|
||||
DryRun: false,
|
||||
UpdateEvents: false,
|
||||
LogFormat: "text",
|
||||
MetricsAddress: ":7979",
|
||||
LogLevel: logrus.InfoLevel.String(),
|
||||
ExoscaleAPIEnvironment: "api",
|
||||
ExoscaleAPIZone: "ch-gva-2",
|
||||
ExoscaleAPIKey: "",
|
||||
ExoscaleAPISecret: "",
|
||||
CRDSourceAPIVersion: "externaldns.k8s.io/v1alpha1",
|
||||
CRDSourceKind: "DNSEndpoint",
|
||||
ServiceTypeFilter: []string{},
|
||||
CFAPIEndpoint: "",
|
||||
CFUsername: "",
|
||||
CFPassword: "",
|
||||
RFC2136Host: []string{""},
|
||||
RFC2136Port: 0,
|
||||
RFC2136Zone: []string{},
|
||||
RFC2136Insecure: false,
|
||||
DefaultTargets: []string{},
|
||||
DigitalOceanAPIPageSize: 50,
|
||||
DomainFilter: []string{},
|
||||
DryRun: false,
|
||||
ExcludeDNSRecordTypes: []string{},
|
||||
ExcludeDomains: []string{},
|
||||
ExcludeTargetNets: []string{},
|
||||
ExcludeUnschedulable: true,
|
||||
ExoscaleAPIEnvironment: "api",
|
||||
ExoscaleAPIKey: "",
|
||||
ExoscaleAPISecret: "",
|
||||
ExoscaleAPIZone: "ch-gva-2",
|
||||
ExposeInternalIPV6: true,
|
||||
FQDNTemplate: "",
|
||||
GatewayLabelFilter: "",
|
||||
GatewayName: "",
|
||||
GatewayNamespace: "",
|
||||
GlooNamespaces: []string{"gloo-system"},
|
||||
GoDaddyAPIKey: "",
|
||||
GoDaddyOTE: false,
|
||||
GoDaddySecretKey: "",
|
||||
GoDaddyTTL: 600,
|
||||
GoogleBatchChangeInterval: time.Second,
|
||||
GoogleBatchChangeSize: 1000,
|
||||
GoogleProject: "",
|
||||
GoogleZoneVisibility: "",
|
||||
IBMCloudConfigFile: "/etc/kubernetes/ibmcloud.json",
|
||||
IBMCloudProxied: false,
|
||||
IgnoreHostnameAnnotation: false,
|
||||
IgnoreIngressRulesSpec: false,
|
||||
IgnoreIngressTLSSpec: false,
|
||||
IngressClassNames: nil,
|
||||
InMemoryZones: []string{},
|
||||
Interval: time.Minute,
|
||||
KubeConfig: "",
|
||||
LabelFilter: labels.Everything().String(),
|
||||
LogFormat: "text",
|
||||
LogLevel: logrus.InfoLevel.String(),
|
||||
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
|
||||
MetricsAddress: ":7979",
|
||||
MinEventSyncInterval: 5 * time.Second,
|
||||
Namespace: "",
|
||||
NAT64Networks: []string{},
|
||||
NS1Endpoint: "",
|
||||
NS1IgnoreSSL: false,
|
||||
OCIConfigFile: "/etc/kubernetes/oci.yaml",
|
||||
OCIZoneCacheDuration: 0 * time.Second,
|
||||
OCIZoneScope: "GLOBAL",
|
||||
Once: false,
|
||||
OVHApiRateLimit: 20,
|
||||
OVHEnableCNAMERelative: false,
|
||||
OVHEndpoint: "ovh-eu",
|
||||
PDNSAPIKey: "",
|
||||
PDNSServer: "http://localhost:8081",
|
||||
PDNSServerID: "localhost",
|
||||
PDNSSkipTLSVerify: false,
|
||||
PiholeApiVersion: "5",
|
||||
PiholePassword: "",
|
||||
PiholeServer: "",
|
||||
PiholeTLSInsecureSkipVerify: false,
|
||||
PluralCluster: "",
|
||||
PluralProvider: "",
|
||||
PodSourceDomain: "",
|
||||
Policy: "sync",
|
||||
Provider: "",
|
||||
ProviderCacheTime: 0,
|
||||
PublishHostIP: false,
|
||||
PublishInternal: false,
|
||||
RegexDomainExclusion: regexp.MustCompile(""),
|
||||
RegexDomainFilter: regexp.MustCompile(""),
|
||||
Registry: "txt",
|
||||
RequestTimeout: time.Second * 30,
|
||||
RFC2136BatchChangeSize: 50,
|
||||
RFC2136GSSTSIG: false,
|
||||
RFC2136Host: []string{""},
|
||||
RFC2136Insecure: false,
|
||||
RFC2136KerberosPassword: "",
|
||||
RFC2136KerberosRealm: "",
|
||||
RFC2136KerberosUsername: "",
|
||||
RFC2136KerberosPassword: "",
|
||||
RFC2136LoadBalancingStrategy: "disabled",
|
||||
RFC2136MinTTL: 0,
|
||||
RFC2136Port: 0,
|
||||
RFC2136SkipTLSVerify: false,
|
||||
RFC2136TAXFR: true,
|
||||
RFC2136TSIGKeyName: "",
|
||||
RFC2136TSIGSecret: "",
|
||||
RFC2136TSIGSecretAlg: "",
|
||||
RFC2136TAXFR: true,
|
||||
RFC2136MinTTL: 0,
|
||||
RFC2136BatchChangeSize: 50,
|
||||
RFC2136UseTLS: false,
|
||||
RFC2136LoadBalancingStrategy: "disabled",
|
||||
RFC2136SkipTLSVerify: false,
|
||||
NS1Endpoint: "",
|
||||
NS1IgnoreSSL: false,
|
||||
TransIPAccountName: "",
|
||||
TransIPPrivateKeyFile: "",
|
||||
DigitalOceanAPIPageSize: 50,
|
||||
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
|
||||
ExcludeDNSRecordTypes: []string{},
|
||||
GoDaddyAPIKey: "",
|
||||
GoDaddySecretKey: "",
|
||||
GoDaddyTTL: 600,
|
||||
GoDaddyOTE: false,
|
||||
IBMCloudProxied: false,
|
||||
IBMCloudConfigFile: "/etc/kubernetes/ibmcloud.json",
|
||||
RFC2136Zone: []string{},
|
||||
ServiceTypeFilter: []string{},
|
||||
SkipperRouteGroupVersion: "zalando.org/v1",
|
||||
Sources: nil,
|
||||
TargetNetFilter: []string{},
|
||||
TencentCloudConfigFile: "/etc/kubernetes/tencent-cloud.json",
|
||||
TencentCloudZoneType: "",
|
||||
PiholeServer: "",
|
||||
PiholePassword: "",
|
||||
PiholeTLSInsecureSkipVerify: false,
|
||||
PiholeApiVersion: "5",
|
||||
PluralCluster: "",
|
||||
PluralProvider: "",
|
||||
WebhookProviderURL: "http://localhost:8888",
|
||||
WebhookProviderReadTimeout: 5 * time.Second,
|
||||
WebhookProviderWriteTimeout: 10 * time.Second,
|
||||
WebhookServer: false,
|
||||
TLSCA: "",
|
||||
TLSClientCert: "",
|
||||
TLSClientCertKey: "",
|
||||
TraefikDisableLegacy: false,
|
||||
TraefikDisableNew: false,
|
||||
NAT64Networks: []string{},
|
||||
ExcludeUnschedulable: true,
|
||||
TransIPAccountName: "",
|
||||
TransIPPrivateKeyFile: "",
|
||||
TXTCacheInterval: 0,
|
||||
TXTEncryptAESKey: "",
|
||||
TXTEncryptEnabled: false,
|
||||
TXTNewFormatOnly: false,
|
||||
TXTOwnerID: "default",
|
||||
TXTPrefix: "",
|
||||
TXTSuffix: "",
|
||||
TXTWildcardReplacement: "",
|
||||
UpdateEvents: false,
|
||||
WebhookProviderReadTimeout: 5 * time.Second,
|
||||
WebhookProviderURL: "http://localhost:8888",
|
||||
WebhookProviderWriteTimeout: 10 * time.Second,
|
||||
WebhookServer: false,
|
||||
ZoneIDFilter: []string{},
|
||||
}
|
||||
|
||||
// NewConfig returns new Config object
|
||||
@ -453,40 +454,41 @@ func App(cfg *Config) *kingpin.Application {
|
||||
app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(defaultConfig.SkipperRouteGroupVersion).StringVar(&cfg.SkipperRouteGroupVersion)
|
||||
|
||||
// Flags related to processing source
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, f5-transportserver, traefik-proxy)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "f5-transportserver", "traefik-proxy")
|
||||
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
|
||||
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||
app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, service and ambassador-host").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
|
||||
app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames)
|
||||
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
||||
app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation)
|
||||
app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when --fqdn-template is set (default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation)
|
||||
app.Flag("ignore-non-host-network-pods", "Ignore pods not running on host network when using pod source (default: true)").BoolVar(&cfg.IgnoreNonHostNetworkPods)
|
||||
app.Flag("ignore-ingress-tls-spec", "Ignore the spec.tls section in Ingress resources (default: false)").BoolVar(&cfg.IgnoreIngressTLSSpec)
|
||||
app.Flag("gateway-name", "Limit Gateways of Route endpoints to a specific name (default: all names)").StringVar(&cfg.GatewayName)
|
||||
app.Flag("gateway-namespace", "Limit Gateways of Route endpoints to a specific namespace (default: all namespaces)").StringVar(&cfg.GatewayNamespace)
|
||||
app.Flag("gateway-label-filter", "Filter Gateways of Route endpoints via label selector (default: all gateways)").StringVar(&cfg.GatewayLabelFilter)
|
||||
app.Flag("compatibility", "Process annotation semantics from legacy implementations (optional, options: mate, molecule, kops-dns-controller)").Default(defaultConfig.Compatibility).EnumVar(&cfg.Compatibility, "", "mate", "molecule", "kops-dns-controller")
|
||||
app.Flag("ignore-ingress-rules-spec", "Ignore the spec.rules section in Ingress resources (default: false)").BoolVar(&cfg.IgnoreIngressRulesSpec)
|
||||
app.Flag("pod-source-domain", "Domain to use for pods records (optional)").Default(defaultConfig.PodSourceDomain).StringVar(&cfg.PodSourceDomain)
|
||||
app.Flag("publish-internal-services", "Allow external-dns to publish DNS records for ClusterIP services (optional)").BoolVar(&cfg.PublishInternal)
|
||||
app.Flag("publish-host-ip", "Allow external-dns to publish host-ip for headless services (optional)").BoolVar(&cfg.PublishHostIP)
|
||||
app.Flag("always-publish-not-ready-addresses", "Always publish also not ready addresses for headless services (optional)").BoolVar(&cfg.AlwaysPublishNotReadyAddresses)
|
||||
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||
app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation)
|
||||
app.Flag("compatibility", "Process annotation semantics from legacy implementations (optional, options: mate, molecule, kops-dns-controller)").Default(defaultConfig.Compatibility).EnumVar(&cfg.Compatibility, "", "mate", "molecule", "kops-dns-controller")
|
||||
app.Flag("connector-source-server", "The server to connect for connector source, valid only when using connector source").Default(defaultConfig.ConnectorSourceServer).StringVar(&cfg.ConnectorSourceServer)
|
||||
app.Flag("crd-source-apiversion", "API version of the CRD for crd source, e.g. `externaldns.k8s.io/v1alpha1`, valid only when using crd source").Default(defaultConfig.CRDSourceAPIVersion).StringVar(&cfg.CRDSourceAPIVersion)
|
||||
app.Flag("crd-source-kind", "Kind of the CRD for the crd source in API group and version specified by crd-source-apiversion").Default(defaultConfig.CRDSourceKind).StringVar(&cfg.CRDSourceKind)
|
||||
app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter)
|
||||
app.Flag("managed-record-types", "Record types to manage; specify multiple times to include many; (default: A, AAAA, CNAME) (supported records: A, AAAA, CNAME, NS, SRV, TXT)").Default("A", "AAAA", "CNAME").StringsVar(&cfg.ManagedDNSRecordTypes)
|
||||
app.Flag("exclude-record-types", "Record types to exclude from management; specify multiple times to exclude many; (optional)").Default().StringsVar(&cfg.ExcludeDNSRecordTypes)
|
||||
app.Flag("default-targets", "Set globally default host/IP that will apply as a target instead of source addresses. Specify multiple times for multiple targets (optional)").StringsVar(&cfg.DefaultTargets)
|
||||
app.Flag("target-net-filter", "Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.TargetNetFilter)
|
||||
app.Flag("exclude-record-types", "Record types to exclude from management; specify multiple times to exclude many; (optional)").Default().StringsVar(&cfg.ExcludeDNSRecordTypes)
|
||||
app.Flag("exclude-target-net", "Exclude target nets (optional)").StringsVar(&cfg.ExcludeTargetNets)
|
||||
app.Flag("traefik-disable-legacy", "Disable listeners on Resources under the traefik.containo.us API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableLegacy)).BoolVar(&cfg.TraefikDisableLegacy)
|
||||
app.Flag("traefik-disable-new", "Disable listeners on Resources under the traefik.io API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableNew)).BoolVar(&cfg.TraefikDisableNew)
|
||||
app.Flag("nat64-networks", "Adding an A record for each AAAA record in NAT64-enabled networks; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.NAT64Networks)
|
||||
app.Flag("exclude-unschedulable", "Exclude nodes that are considered unschedulable (default: true)").Default(strconv.FormatBool(defaultConfig.ExcludeUnschedulable)).BoolVar(&cfg.ExcludeUnschedulable)
|
||||
app.Flag("expose-internal-ipv6", "When using the node source, expose internal IPv6 addresses (optional). Default is true.").BoolVar(&cfg.ExposeInternalIPV6)
|
||||
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
||||
app.Flag("gateway-label-filter", "Filter Gateways of Route endpoints via label selector (default: all gateways)").StringVar(&cfg.GatewayLabelFilter)
|
||||
app.Flag("gateway-name", "Limit Gateways of Route endpoints to a specific name (default: all names)").StringVar(&cfg.GatewayName)
|
||||
app.Flag("gateway-namespace", "Limit Gateways of Route endpoints to a specific namespace (default: all namespaces)").StringVar(&cfg.GatewayNamespace)
|
||||
app.Flag("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when --fqdn-template is set (default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation)
|
||||
app.Flag("ignore-ingress-rules-spec", "Ignore the spec.rules section in Ingress resources (default: false)").BoolVar(&cfg.IgnoreIngressRulesSpec)
|
||||
app.Flag("ignore-ingress-tls-spec", "Ignore the spec.tls section in Ingress resources (default: false)").BoolVar(&cfg.IgnoreIngressTLSSpec)
|
||||
app.Flag("ignore-non-host-network-pods", "Ignore pods not running on host network when using pod source (default: true)").BoolVar(&cfg.IgnoreNonHostNetworkPods)
|
||||
app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames)
|
||||
app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, service and ambassador-host").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
|
||||
managedRecordTypesHelp := fmt.Sprintf("Record types to manage; specify multiple times to include many; (default: %s) (supported records: A, AAAA, CNAME, NS, SRV, TXT)", strings.Join(defaultConfig.ManagedDNSRecordTypes, ","))
|
||||
app.Flag("managed-record-types", managedRecordTypesHelp).Default(defaultConfig.ManagedDNSRecordTypes...).StringsVar(&cfg.ManagedDNSRecordTypes)
|
||||
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||
app.Flag("nat64-networks", "Adding an A record for each AAAA record in NAT64-enabled networks; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.NAT64Networks)
|
||||
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
|
||||
app.Flag("pod-source-domain", "Domain to use for pods records (optional)").Default(defaultConfig.PodSourceDomain).StringVar(&cfg.PodSourceDomain)
|
||||
app.Flag("publish-host-ip", "Allow external-dns to publish host-ip for headless services (optional)").BoolVar(&cfg.PublishHostIP)
|
||||
app.Flag("publish-internal-services", "Allow external-dns to publish DNS records for ClusterIP services (optional)").BoolVar(&cfg.PublishInternal)
|
||||
app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter)
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, pod, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress, f5-virtualserver, f5-transportserver, traefik-proxy)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress", "f5-virtualserver", "f5-transportserver", "traefik-proxy")
|
||||
app.Flag("target-net-filter", "Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.TargetNetFilter)
|
||||
app.Flag("traefik-disable-legacy", "Disable listeners on Resources under the traefik.containo.us API Group").Default(strconv.FormatBool(defaultConfig.TraefikDisableLegacy)).BoolVar(&cfg.TraefikDisableLegacy)
|
||||
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", "ibmcloud", "inmemory", "linode", "ns1", "oci", "ovh", "pdns", "pihole", "plural", "rfc2136", "scaleway", "skydns", "tencentcloud", "transip", "ultradns", "webhook"}
|
||||
|
@ -265,6 +265,8 @@ func (p *Plan) Calculate() *Plan {
|
||||
Current: p.Current,
|
||||
Desired: p.Desired,
|
||||
Changes: changes,
|
||||
// The default for ExternalDNS is to always only consider A/AAAA and CNAMEs.
|
||||
// Everything else is an add on or something to be considered.
|
||||
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
|
||||
}
|
||||
|
||||
|
@ -367,9 +367,22 @@ func (suite *PlanTestSuite) TestSyncSecondRoundWithProviderSpecificNoChange() {
|
||||
}
|
||||
|
||||
changes := p.Calculate().Changes
|
||||
if changes.HasChanges() {
|
||||
suite.T().Fatal("test should not have changes")
|
||||
suite.Assert().False(changes.HasChanges())
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestHasChanges() {
|
||||
current := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificTrue}
|
||||
desired := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificFalse}
|
||||
|
||||
p := &Plan{
|
||||
Policies: []Policy{&SyncPolicy{}},
|
||||
Current: current,
|
||||
Desired: desired,
|
||||
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
|
||||
}
|
||||
|
||||
changes := p.Calculate().Changes
|
||||
suite.Assert().True(changes.HasChanges())
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestSyncSecondRoundWithProviderSpecificRemoval() {
|
||||
|
Loading…
Reference in New Issue
Block a user