mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-05 17:16:59 +02:00
Adds TLS flags for pdns provider
This commit is contained in:
parent
e34bf552d6
commit
15b279a4bc
23
internal/testresources/ca.pem
Normal file
23
internal/testresources/ca.pem
Normal file
@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDwDCCAqigAwIBAgIUYsFawvERY3xGTHmKWq/78Cp70AIwDQYJKoZIhvcNAQEL
|
||||
BQAweDEQMA4GA1UEBhMHQ291bnRyeTERMA8GA1UEBxMITG9jYWxpdHkxFTATBgNV
|
||||
BAoTDE9yZ2FuaXphdGlvbjEbMBkGA1UECxMST3JnYW5pemF0aW9uYWxVbml0MR0w
|
||||
GwYDVQQDExRleHRlcm5hbC1kbnMgdGVzdCBDQTAeFw0xODA2MTQyMTE5MDBaFw0y
|
||||
MzA2MTMyMTE5MDBaMHgxEDAOBgNVBAYTB0NvdW50cnkxETAPBgNVBAcTCExvY2Fs
|
||||
aXR5MRUwEwYDVQQKEwxPcmdhbml6YXRpb24xGzAZBgNVBAsTEk9yZ2FuaXphdGlv
|
||||
bmFsVW5pdDEdMBsGA1UEAxMUZXh0ZXJuYWwtZG5zIHRlc3QgQ0EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMEaMix69YrVXPtfUsOgz5RJqaAlitw+HV
|
||||
BaYv7BbcChiidYQ+/iKo26HA5vjBP5xOMNYTnVowXA+q+RmMGfhSc+j9CiJeADP0
|
||||
oxjSNq/w5Xb/IFIHSjr+dEdavcdsV95y3BYB8PkopjXEmNgbEgPbHNuJMQkd89rC
|
||||
2ztSIPHbjhorrauAGm8cgzdKK6Tnxhey9yQralIgdrOHXMTOZrWywTPiUtIuxrn5
|
||||
XfIaylfqQO+Q79rEGhk9YQuFUqs+GDDp/PiCGC56/IbF7NVLEdrJIc6Tf9Rg2/K/
|
||||
9ydeZ5hcaM542Q2UoXIbRp8jn/J1Xr3mcxhpnhJN4TcjLalnSY6tAgMBAAGjQjBA
|
||||
MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTym+5y
|
||||
SEghmx5Xr+wd5Z0V+9AWxDANBgkqhkiG9w0BAQsFAAOCAQEAlGaKZY40apdmROAx
|
||||
usSLJjgVIw5GjX7lNw6BqorbQavexPjghfhB1TSpFOvHCz7s164Eq18+wfbzfnR5
|
||||
L+Xza+eibvkgO8ZojGMFXR+5NCbM2cPBTmWZVNVRoZQX6j5RT/DeLcjEKDBWZBdP
|
||||
IxAQCFprxHgBZeHOfzvombzdbDM5To9ff+3gaunMbWs7YAmpv1czRc0F0arXg+mA
|
||||
AzG4fc94lJ5oMF6sClZ1rbJjLcohtINx6HstUzLxlAcgJMJcvvJrrdTkzJSCOmE6
|
||||
a52RJX6qVaZNHCXDooiy2uDapXyA4sPCt4n3KhRfP+JGp6Xmg10rm7ga8+ZUCYae
|
||||
UyE4mA==
|
||||
-----END CERTIFICATE-----
|
27
internal/testresources/client-cert-key.pem
Normal file
27
internal/testresources/client-cert-key.pem
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAykDCIA6Q0p8HJLx3njenAqvKvHGwJzjLP+tw4iq8J3//aEon
|
||||
e23t9CwGW9YVNTM4Xu6n0+exUsUK4LweHRTYLmYkTHUc+pB9+XpQ+wKutmxv+zhk
|
||||
uWi+4u6pqC6e8TSuURs3c9ML2TxCTIRubd3hPRGMizo3POuQ8iaRo8icfdQcv/XE
|
||||
bieB8ma5ZUkRxkY+Mu+MYOsleoIpSByej18ycJkVkipV6CeSxenCsQaeAaJPTOVO
|
||||
9rYZL3F3fNHXezIpCmw3sgCiudQ1MvPKGs4G5UahCO0OSp42IMUodYxvQ0G1o5uZ
|
||||
9k9R8Xcumso61xHM/ZCkzqJ89P/2zXyUC7c2OQIDAQABAoIBABoHL3RUq4qPcKnn
|
||||
nzU7UEDlvtd1ggfqJS36rLJOcZxbupC/Skl2IjNUHxVefag1CUIeUHbS0F0ognfd
|
||||
fbqcXh3Kg01bnPkZ8zxR424KMFXFqruXzE6YDkjCEg9UwJul/fDuIbrEJDg2qwmR
|
||||
2WxGK6BiS8X3Hfi3EBY5pHCBdrIyiVWZn8CYYmiBhJehdNHEwtIk+Bo8mWBTOOpS
|
||||
x9e1czYICM39zyZQtuLvI/CIcSg1uyRL19r7KrAoBS2o6ijDrp5KqCyAVL9UYq5m
|
||||
B3k/KltYi6d3HtcHwuMHPKNpWfOQCKu7MDX+ZNi7E6LrPxWqrPoiZ5xzAQPQHD3B
|
||||
e3fmt6ECgYEA5z5z3kxjF6EYttzDMylUghTfPs/vyhecFKzbcipdMJNs8o9KnHF9
|
||||
WgH7JaPU8cYe8CluQWZn6ByxdaB7G56wfHrYYCm5pbsuxlkoqqLMmAmVBPZVMhEy
|
||||
thoxi4PxAdcs5HsqwYbazpToYZ6ktvknIUKOp24oQgYUG5T0mkNm910CgYEA3+fE
|
||||
4Mh2rikegQLYar9gsFAXpBjxiMRQlUH23Qk9p21AkczTjGpYeV4v2LxxTYKiaZRJ
|
||||
8X4Ab745j+yLbsYMxZKihNCQSLTK44FSgK6fSEs+yHLpQjT4V5IyvD+tHMan9n/s
|
||||
YqDppse1GHGGxF7N4FatrQk5Kz8FG9EYa6BNWI0CgYBYXALGRIXwt3vME9r6p6ZE
|
||||
9li/lZDYteDL/aj0nL9zGkIdBSfLU4pEZFFk9o8du0iDGDGrB8hYZu5gNewUh7SE
|
||||
PCSFyivH6hhbbiId4Ysv5Slt9fpj4TJxZtzbpJTo0SG0RGP4AuGE4l1RP99MkzOi
|
||||
f94ml+8GG3B/gZFdiLfFeQKBgQC9pDxoduGuWT1w38wVfcqTCwM7BbVttXjbMme4
|
||||
hx8lM6/Azc9P2rLc+R1lYRZGJCMTcXm/hI0yF9gBQsRGKpCetrfX7h6Gtjoxv1L1
|
||||
kvFt9e1TMaDHZr4Azd8S+ovRF6Ejcu3wC4JatEN6VI1kvTd6j2/CY1F8g3/8M3mP
|
||||
jtJz8QKBgCL2XDev1Vls2hzqrNqjNehYVAqTNdNNr2jzCR1g8AMFqSy7k/4gFtu/
|
||||
bXBnSKnGrtmb+VWKDMwNy7oe6g6haFLTjPbnl8/afKBbH0WQzlvVJgKWSX1faWTG
|
||||
1WMRAqD8nIdcYbfj7AhmNGL6zYGr0g+YP9CF+j6je2Rb0so+S5cZ
|
||||
-----END RSA PRIVATE KEY-----
|
24
internal/testresources/client-cert.pem
Normal file
24
internal/testresources/client-cert.pem
Normal file
@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEEzCCAvugAwIBAgIUJxJZIg35oCO6747gR3c9ZkQc8TMwDQYJKoZIhvcNAQEL
|
||||
BQAweDEQMA4GA1UEBhMHQ291bnRyeTERMA8GA1UEBxMITG9jYWxpdHkxFTATBgNV
|
||||
BAoTDE9yZ2FuaXphdGlvbjEbMBkGA1UECxMST3JnYW5pemF0aW9uYWxVbml0MR0w
|
||||
GwYDVQQDExRleHRlcm5hbC1kbnMgdGVzdCBDQTAeFw0xODA2MTQyMTIzMDBaFw0y
|
||||
MzA2MTMyMTIzMDBaMIGIMRAwDgYDVQQGEwdDb3VudHJ5MREwDwYDVQQHEwhMb2Nh
|
||||
bGl0eTEVMBMGA1UEChMMT3JnYW5pemF0aW9uMRswGQYDVQQLExJPcmdhbml6YXRp
|
||||
b25hbFVuaXQxLTArBgNVBAMTJGV4dGVybmFsLWRucyB0ZXN0IGNsaWVudCBjZXJ0
|
||||
aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpAwiAOkNKf
|
||||
ByS8d543pwKryrxxsCc4yz/rcOIqvCd//2hKJ3tt7fQsBlvWFTUzOF7up9PnsVLF
|
||||
CuC8Hh0U2C5mJEx1HPqQffl6UPsCrrZsb/s4ZLlovuLuqagunvE0rlEbN3PTC9k8
|
||||
QkyEbm3d4T0RjIs6NzzrkPImkaPInH3UHL/1xG4ngfJmuWVJEcZGPjLvjGDrJXqC
|
||||
KUgcno9fMnCZFZIqVegnksXpwrEGngGiT0zlTva2GS9xd3zR13syKQpsN7IAornU
|
||||
NTLzyhrOBuVGoQjtDkqeNiDFKHWMb0NBtaObmfZPUfF3LprKOtcRzP2QpM6ifPT/
|
||||
9s18lAu3NjkCAwEAAaOBgzCBgDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYI
|
||||
KwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUA+Do/9mVdkyYJAPYUzbr
|
||||
9FBi8gMwHwYDVR0jBBgwFoAU8pvuckhIIZseV6/sHeWdFfvQFsQwCwYDVR0RBAQw
|
||||
AoIAMA0GCSqGSIb3DQEBCwUAA4IBAQBFzN/cqkVjGYaQzCpOWVgizIwBhGFRfYGY
|
||||
Cw5m9HaZIMjbSxt55NhRTFm6Q5qFfD2KXXPueEUL4U5iPg+LPHrUfNmKiJtUcKc8
|
||||
M2FJimb7nRsw46F+tRt0lgM5sDeqe2QUlNTKFKaxnHUDqWt4mW7adzog3sX7UfGB
|
||||
yvbJR9Y6cEMlG2it3rl9/ZiAJnTJSvCqBV9QlBAkCCh0JgJEtPLubz97BVGkMORh
|
||||
+ZgHCw/A9sew/7Krpbyp/NtHeFVsa8tH8wivnaGeITGD4J23U9E3YYUaNPN7kBcX
|
||||
DuFCSEKHGsbAvH2Igxkk+rD5T8d6RwJ98jkXOYXCxGmGBuDEkyGZ
|
||||
-----END CERTIFICATE-----
|
15
main.go
15
main.go
@ -156,7 +156,20 @@ func main() {
|
||||
case "designate":
|
||||
p, err = provider.NewDesignateProvider(domainFilter, cfg.DryRun)
|
||||
case "pdns":
|
||||
p, err = provider.NewPDNSProvider(cfg.PDNSServer, cfg.PDNSAPIKey, domainFilter, cfg.DryRun)
|
||||
p, err = provider.NewPDNSProvider(
|
||||
provider.PDNSConfig{
|
||||
DomainFilter: domainFilter,
|
||||
DryRun: cfg.DryRun,
|
||||
Server: cfg.PDNSServer,
|
||||
APIKey: cfg.PDNSAPIKey,
|
||||
TLSConfig: provider.TLSConfig{
|
||||
TLSEnabled: cfg.PDNSTLSEnabled,
|
||||
CAFilePath: cfg.TLSCA,
|
||||
ClientCertFilePath: cfg.TLSClientCert,
|
||||
ClientCertKeyFilePath: cfg.TLSClientCertKey,
|
||||
},
|
||||
},
|
||||
)
|
||||
default:
|
||||
log.Fatalf("unknown dns provider: %s", cfg.Provider)
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ type Config struct {
|
||||
InMemoryZones []string
|
||||
PDNSServer string
|
||||
PDNSAPIKey string
|
||||
PDNSTLSEnabled bool
|
||||
TLSCA string
|
||||
TLSClientCert string
|
||||
TLSClientCertKey string
|
||||
Policy string
|
||||
Registry string
|
||||
TXTOwnerID string
|
||||
@ -111,6 +115,10 @@ var defaultConfig = &Config{
|
||||
InMemoryZones: []string{},
|
||||
PDNSServer: "http://localhost:8081",
|
||||
PDNSAPIKey: "",
|
||||
PDNSTLSEnabled: false,
|
||||
TLSCA: "",
|
||||
TLSClientCert: "",
|
||||
TLSClientCertKey: "",
|
||||
Policy: "sync",
|
||||
Registry: "txt",
|
||||
TXTOwnerID: "default",
|
||||
@ -138,6 +146,9 @@ func (cfg *Config) String() string {
|
||||
if temp.InfobloxWapiPassword != "" {
|
||||
temp.InfobloxWapiPassword = passwordMask
|
||||
}
|
||||
if temp.PDNSAPIKey != "" {
|
||||
temp.PDNSAPIKey = ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%+v", temp)
|
||||
}
|
||||
@ -195,7 +206,13 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
|
||||
app.Flag("inmemory-zone", "Provide a list of pre-configured zones for the inmemory provider; specify multiple times for multiple zones (optional)").Default("").StringsVar(&cfg.InMemoryZones)
|
||||
app.Flag("pdns-server", "When using the PowerDNS/PDNS provider, specify the URL to the pdns server (required when --provider=pdns)").Default(defaultConfig.PDNSServer).StringVar(&cfg.PDNSServer)
|
||||
app.Flag("pdns-api-key", "When using the PowerDNS/PDNS provider, specify the URL to the pdns server (required when --provider=pdns)").Default(defaultConfig.PDNSAPIKey).StringVar(&cfg.PDNSAPIKey)
|
||||
app.Flag("pdns-api-key", "When using the PowerDNS/PDNS provider, specify the API key to use to authorize requests (required when --provider=pdns)").Default(defaultConfig.PDNSAPIKey).StringVar(&cfg.PDNSAPIKey)
|
||||
app.Flag("pdns-tls-enabled", "When using the PowerDNS/PDNS provider, specify whether to use TLS (default: false, requires --tls-ca, optionally specify --tls-client-cert and --tls-client-cert-key)").Default(strconv.FormatBool(defaultConfig.PDNSTLSEnabled)).BoolVar(&cfg.PDNSTLSEnabled)
|
||||
|
||||
// Flags related to TLS communication
|
||||
app.Flag("tls-ca", "When using TLS communication, the path to the certificate authority to verify server communications (optionally specify --tls-client-cert for two-way TLS)").Default(defaultConfig.TLSCA).StringVar(&cfg.TLSCA)
|
||||
app.Flag("tls-client-cert", "When using TLS communication, the path to the certificate to present as a client (not required for TLS)").Default(defaultConfig.TLSClientCert).StringVar(&cfg.TLSClientCert)
|
||||
app.Flag("tls-client-cert-key", "When using TLS communication, the path to the certificate key to use with the client certificate (not required for TLS)").Default(defaultConfig.TLSClientCertKey).StringVar(&cfg.TLSClientCertKey)
|
||||
|
||||
// Flags related to policies
|
||||
app.Flag("policy", "Modify how DNS records are sychronized between sources and providers (default: sync, options: sync, upsert-only)").Default(defaultConfig.Policy).EnumVar(&cfg.Policy, "sync", "upsert-only")
|
||||
|
@ -94,6 +94,10 @@ var (
|
||||
InMemoryZones: []string{"example.org", "company.com"},
|
||||
PDNSServer: "http://ns.example.com:8081",
|
||||
PDNSAPIKey: "some-secret-key",
|
||||
PDNSTLSEnabled: true,
|
||||
TLSCA: "/path/to/ca.crt",
|
||||
TLSClientCert: "/path/to/cert.pem",
|
||||
TLSClientCertKey: "/path/to/key.pem",
|
||||
Policy: "upsert-only",
|
||||
Registry: "noop",
|
||||
TXTOwnerID: "owner-1",
|
||||
@ -150,6 +154,10 @@ func TestParseFlags(t *testing.T) {
|
||||
"--inmemory-zone=company.com",
|
||||
"--pdns-server=http://ns.example.com:8081",
|
||||
"--pdns-api-key=some-secret-key",
|
||||
"--pdns-tls-enabled",
|
||||
"--tls-ca=/path/to/ca.crt",
|
||||
"--tls-client-cert=/path/to/cert.pem",
|
||||
"--tls-client-cert-key=/path/to/key.pem",
|
||||
"--no-infoblox-ssl-verify",
|
||||
"--domain-filter=example.org",
|
||||
"--domain-filter=company.com",
|
||||
@ -199,6 +207,10 @@ func TestParseFlags(t *testing.T) {
|
||||
"EXTERNAL_DNS_DOMAIN_FILTER": "example.org\ncompany.com",
|
||||
"EXTERNAL_DNS_PDNS_SERVER": "http://ns.example.com:8081",
|
||||
"EXTERNAL_DNS_PDNS_API_KEY": "some-secret-key",
|
||||
"EXTERNAL_DNS_PDNS_TLS_ENABLED": "1",
|
||||
"EXTERNAL_DNS_TLS_CA": "/path/to/ca.crt",
|
||||
"EXTERNAL_DNS_TLS_CLIENT_CERT": "/path/to/cert.pem",
|
||||
"EXTERNAL_DNS_TLS_CLIENT_CERT_KEY": "/path/to/key.pem",
|
||||
"EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2",
|
||||
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
|
||||
"EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role",
|
||||
@ -253,10 +265,12 @@ func TestPasswordsNotLogged(t *testing.T) {
|
||||
cfg := Config{
|
||||
DynPassword: "dyn-pass",
|
||||
InfobloxWapiPassword: "infoblox-pass",
|
||||
PDNSAPIKey: "pdns-api-key",
|
||||
}
|
||||
|
||||
s := cfg.String()
|
||||
|
||||
assert.False(t, strings.Contains(s, "dyn-pass"))
|
||||
assert.False(t, strings.Contains(s, "infoblox-pass"))
|
||||
assert.False(t, strings.Contains(s, "pdns-api-key"))
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (c *cache) Get(link string) *endpoint.Endpoint {
|
||||
return result.ep
|
||||
}
|
||||
|
||||
// DynConfig hold connection parameters to dyn.com and interanl state
|
||||
// DynConfig hold connection parameters to dyn.com and internal state
|
||||
type DynConfig struct {
|
||||
DomainFilter DomainFilter
|
||||
ZoneIDFilter ZoneIDFilter
|
||||
|
129
provider/pdns.go
129
provider/pdns.go
@ -32,6 +32,10 @@ import (
|
||||
pgo "github.com/ffledgling/pdns-go"
|
||||
"github.com/kubernetes-incubator/external-dns/endpoint"
|
||||
"github.com/kubernetes-incubator/external-dns/plan"
|
||||
"net"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type pdnsChangeType string
|
||||
@ -57,6 +61,106 @@ const (
|
||||
retryAfterTime = 250 * time.Millisecond
|
||||
)
|
||||
|
||||
type PDNSConfig struct {
|
||||
DomainFilter DomainFilter
|
||||
DryRun bool
|
||||
Server string
|
||||
APIKey string
|
||||
TLSConfig TLSConfig
|
||||
}
|
||||
|
||||
type TLSConfig struct {
|
||||
TLSEnabled bool
|
||||
CAFilePath string
|
||||
ClientCertFilePath string
|
||||
ClientCertKeyFilePath string
|
||||
}
|
||||
|
||||
func (tlsConfig *TLSConfig) setHttpClient(pdnsClientConfig *pgo.Configuration) error {
|
||||
if !tlsConfig.TLSEnabled {
|
||||
if tlsConfig.CAFilePath != "" {
|
||||
return errors.New("certificate authority file path was specified, but TLS was not enabled")
|
||||
}
|
||||
if tlsConfig.ClientCertFilePath != "" {
|
||||
return errors.New("client certificate file path was specified, but TLS was not enabled")
|
||||
}
|
||||
if tlsConfig.ClientCertKeyFilePath != "" {
|
||||
return errors.New("client certificate key file path was specified, but TLS was not enabled")
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
log.Debug("Configuring TLS for PDNS Provider.")
|
||||
if tlsConfig.CAFilePath == "" {
|
||||
return errors.New("certificate authority file path must be specified if TLS is enabled")
|
||||
}
|
||||
if tlsConfig.ClientCertFilePath == "" && tlsConfig.ClientCertKeyFilePath != "" ||
|
||||
tlsConfig.ClientCertFilePath != "" && tlsConfig.ClientCertKeyFilePath == "" {
|
||||
return errors.New("client certificate and client certificate key should be specified together if at all")
|
||||
}
|
||||
|
||||
certificateAuthority, err := loadCertificateAuthority(tlsConfig.CAFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certificate, err := loadCertificate(tlsConfig.ClientCertFilePath, tlsConfig.ClientCertKeyFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Timeouts taken from net.http.DefaultTransport
|
||||
transporter := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Certificates: certificate,
|
||||
RootCAs: certificateAuthority,
|
||||
},
|
||||
}
|
||||
pdnsClientConfig.HTTPClient = &http.Client{
|
||||
Transport: transporter,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCertificateAuthority(certificateAuthorityFilePath string) (*x509.CertPool, error) {
|
||||
pool := x509.NewCertPool()
|
||||
|
||||
pem, err := ioutil.ReadFile(certificateAuthorityFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ok := pool.AppendCertsFromPEM(pem)
|
||||
if !ok {
|
||||
return nil, errors.New("error appending certificate to pool")
|
||||
}
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func loadCertificate(certificateFilePath string, certificateKeyFilePath string) ([]tls.Certificate, error) {
|
||||
if certificateFilePath == "" || certificateKeyFilePath == "" {
|
||||
return []tls.Certificate{}, nil
|
||||
}
|
||||
certificate, err := tls.LoadX509KeyPair(certificateFilePath, certificateKeyFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []tls.Certificate{certificate}, nil
|
||||
}
|
||||
|
||||
// Function for debug printing
|
||||
func stringifyHTTPResponseBody(r *http.Response) (body string) {
|
||||
|
||||
@ -151,37 +255,40 @@ type PDNSProvider struct {
|
||||
}
|
||||
|
||||
// NewPDNSProvider initializes a new PowerDNS based Provider.
|
||||
func NewPDNSProvider(server string, apikey string, domainFilter DomainFilter, dryRun bool) (*PDNSProvider, error) {
|
||||
func NewPDNSProvider(config PDNSConfig) (*PDNSProvider, error) {
|
||||
|
||||
// Do some input validation
|
||||
|
||||
if apikey == "" {
|
||||
if config.APIKey == "" {
|
||||
return nil, errors.New("Missing API Key for PDNS. Specify using --pdns-api-key=")
|
||||
}
|
||||
|
||||
// The default for when no --domain-filter is passed is [""], instead of [], so we check accordingly.
|
||||
if len(domainFilter.filters) != 1 && domainFilter.filters[0] != "" {
|
||||
if len(config.DomainFilter.filters) != 1 && config.DomainFilter.filters[0] != "" {
|
||||
return nil, errors.New("PDNS Provider does not support domain filter")
|
||||
}
|
||||
// We do not support dry running, exit safely instead of surprising the user
|
||||
// TODO: Add Dry Run support
|
||||
if dryRun {
|
||||
if config.DryRun {
|
||||
return nil, errors.New("PDNS Provider does not currently support dry-run")
|
||||
}
|
||||
|
||||
if server == "localhost" {
|
||||
if config.Server == "localhost" {
|
||||
log.Warnf("PDNS Server is set to localhost, this may not be what you want. Specify using --pdns-server=")
|
||||
}
|
||||
|
||||
cfg := pgo.NewConfiguration()
|
||||
cfg.Host = server
|
||||
cfg.BasePath = server + apiBase
|
||||
pdnsClientConfig := pgo.NewConfiguration()
|
||||
pdnsClientConfig.Host = config.Server
|
||||
pdnsClientConfig.BasePath = config.Server + apiBase
|
||||
if err := config.TLSConfig.setHttpClient(pdnsClientConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
provider := &PDNSProvider{
|
||||
client: &PDNSAPIClient{
|
||||
dryRun: dryRun,
|
||||
authCtx: context.WithValue(context.TODO(), pgo.ContextAPIKey, pgo.APIKey{Key: apikey}),
|
||||
client: pgo.NewAPIClient(cfg),
|
||||
dryRun: config.DryRun,
|
||||
authCtx: context.WithValue(context.TODO(), pgo.ContextAPIKey, pgo.APIKey{Key: config.APIKey}),
|
||||
client: pgo.NewAPIClient(pdnsClientConfig),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -476,22 +476,148 @@ type NewPDNSProviderTestSuite struct {
|
||||
}
|
||||
|
||||
func (suite *NewPDNSProviderTestSuite) TestPDNSProviderCreate() {
|
||||
// Function definition: NewPDNSProvider(server string, apikey string, domainFilter DomainFilter, dryRun bool) (*PDNSProvider, error)
|
||||
|
||||
_, err := NewPDNSProvider("http://localhost:8081", "", NewDomainFilter([]string{""}), false)
|
||||
_, err := NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
})
|
||||
assert.Error(suite.T(), err, "--pdns-api-key should be specified")
|
||||
|
||||
_, err = NewPDNSProvider("http://localhost:8081", "foo", NewDomainFilter([]string{"example.com", "example.org"}), false)
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{"example.com", "example.org"}),
|
||||
})
|
||||
assert.Error(suite.T(), err, "--domainfilter should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider("http://localhost:8081", "foo", NewDomainFilter([]string{""}), true)
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
DryRun: true,
|
||||
})
|
||||
assert.Error(suite.T(), err, "--dry-run should raise an error")
|
||||
|
||||
// This is our "regular" code path, no error should be thrown
|
||||
_, err = NewPDNSProvider("http://localhost:8081", "foo", NewDomainFilter([]string{""}), false)
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
})
|
||||
assert.Nil(suite.T(), err, "Regular case should raise no error")
|
||||
}
|
||||
|
||||
func (suite *NewPDNSProviderTestSuite) TestPDNSProviderCreateTLS() {
|
||||
|
||||
_, err := NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
})
|
||||
assert.Nil(suite.T(), err, "Omitted TLS Config case should raise no error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: false,
|
||||
},
|
||||
})
|
||||
assert.Nil(suite.T(), err, "Disabled TLS Config should raise no error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: false,
|
||||
CAFilePath: "/path/to/ca.crt",
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Disabled TLS Config with --tls-ca should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: false,
|
||||
ClientCertFilePath: "/path/to/cert.pem",
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Disabled TLS Config with --tls-client-cert should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: false,
|
||||
ClientCertKeyFilePath: "/path/to/cert-key.pem",
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Disabled TLS Config with --tls-client-cert-key should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: true,
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Enabled TLS Config without --tls-ca should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: true,
|
||||
CAFilePath: "../internal/testresources/ca.pem",
|
||||
},
|
||||
})
|
||||
assert.Nil(suite.T(), err, "Enabled TLS Config with --tls-ca should raise no error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: true,
|
||||
CAFilePath: "../internal/testresources/ca.pem",
|
||||
ClientCertFilePath: "../internal/testresources/client-cert.pem",
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Enabled TLS Config with --tls-client-cert only should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: true,
|
||||
CAFilePath: "../internal/testresources/ca.pem",
|
||||
ClientCertKeyFilePath: "../internal/testresources/client-cert-key.pem",
|
||||
},
|
||||
})
|
||||
assert.Error(suite.T(), err, "Enabled TLS Config with --tls-client-cert-key only should raise an error")
|
||||
|
||||
_, err = NewPDNSProvider(PDNSConfig{
|
||||
Server: "http://localhost:8081",
|
||||
APIKey: "foo",
|
||||
DomainFilter: NewDomainFilter([]string{""}),
|
||||
TLSConfig: TLSConfig{
|
||||
TLSEnabled: true,
|
||||
CAFilePath: "../internal/testresources/ca.pem",
|
||||
ClientCertFilePath: "../internal/testresources/client-cert.pem",
|
||||
ClientCertKeyFilePath: "../internal/testresources/client-cert-key.pem",
|
||||
},
|
||||
})
|
||||
assert.Nil(suite.T(), err, "Enabled TLS Config with all flags should raise no error")
|
||||
}
|
||||
|
||||
func (suite *NewPDNSProviderTestSuite) TestPDNSRRSetToEndpoints() {
|
||||
// Function definition: convertRRSetToEndpoints(rr pgo.RrSet) (endpoints []*endpoint.Endpoint, _ error)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user