mirror of
https://github.com/coredns/coredns.git
synced 2025-12-07 19:05:19 -05:00
Add TLS support for k8s middleware (#289)
* Added TLS to k8s client Added options for TLS kubernetes client connection. * Fix k8s TLS config option parsing Brings config option parsing for kubernetes TLS in line with recent changes. * Put TLS config on one line Put kubernetes tls config on one line to match style established in etcd tls config. * Add tls option to README
This commit is contained in:
committed by
Miek Gieben
parent
b9cf32f7a9
commit
15297c8e63
@@ -40,7 +40,9 @@ This is the default kubernetes setup, with everything specified in full:
|
|||||||
# Example values: 60s, 5m, 1h
|
# Example values: 60s, 5m, 1h
|
||||||
resyncperiod 5m
|
resyncperiod 5m
|
||||||
# Use url for k8s API endpoint
|
# Use url for k8s API endpoint
|
||||||
endpoint http://localhost:8080
|
endpoint https://k8sendpoint:8080
|
||||||
|
# The tls cert, key and the CA cert filenames
|
||||||
|
tls cert key cacert
|
||||||
# Assemble k8s record names with the template
|
# Assemble k8s record names with the template
|
||||||
template {service}.{namespace}.{zone}
|
template {service}.{namespace}.{zone}
|
||||||
# Only expose the k8s namespace "demo"
|
# Only expose the k8s namespace "demo"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
unversionedapi "k8s.io/kubernetes/pkg/api/unversioned"
|
unversionedapi "k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
unversionedclient "k8s.io/kubernetes/pkg/client/unversioned"
|
unversionedclient "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
@@ -29,6 +30,9 @@ type Kubernetes struct {
|
|||||||
Zones []string
|
Zones []string
|
||||||
Proxy proxy.Proxy // Proxy for looking up names during the resolution process
|
Proxy proxy.Proxy // Proxy for looking up names during the resolution process
|
||||||
APIEndpoint string
|
APIEndpoint string
|
||||||
|
APICertAuth string
|
||||||
|
APIClientCert string
|
||||||
|
APIClientKey string
|
||||||
APIConn *dnsController
|
APIConn *dnsController
|
||||||
ResyncPeriod time.Duration
|
ResyncPeriod time.Duration
|
||||||
NameTemplate *nametemplate.NameTemplate
|
NameTemplate *nametemplate.NameTemplate
|
||||||
@@ -37,23 +41,41 @@ type Kubernetes struct {
|
|||||||
Selector *labels.Selector
|
Selector *labels.Selector
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitKubeCache initializes a new Kubernetes cache.
|
func (k *Kubernetes) getClientConfig() (*restclient.Config, error) {
|
||||||
// TODO(miek): is this correct?
|
|
||||||
func (k *Kubernetes) InitKubeCache() error {
|
|
||||||
// For a custom api server or running outside a k8s cluster
|
// For a custom api server or running outside a k8s cluster
|
||||||
// set URL in env.KUBERNETES_MASTER or set endpoint in Corefile
|
// set URL in env.KUBERNETES_MASTER or set endpoint in Corefile
|
||||||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||||
overrides := &clientcmd.ConfigOverrides{}
|
overrides := &clientcmd.ConfigOverrides{}
|
||||||
|
clusterinfo := clientcmdapi.Cluster{}
|
||||||
|
authinfo := clientcmdapi.AuthInfo{}
|
||||||
if len(k.APIEndpoint) > 0 {
|
if len(k.APIEndpoint) > 0 {
|
||||||
overrides.ClusterInfo = clientcmdapi.Cluster{Server: k.APIEndpoint}
|
clusterinfo.Server = k.APIEndpoint
|
||||||
}
|
}
|
||||||
|
if len(k.APICertAuth) > 0 {
|
||||||
|
clusterinfo.CertificateAuthority = k.APICertAuth
|
||||||
|
}
|
||||||
|
if len(k.APIClientCert) > 0 {
|
||||||
|
authinfo.ClientCertificate = k.APIClientCert
|
||||||
|
}
|
||||||
|
if len(k.APIClientKey) > 0 {
|
||||||
|
authinfo.ClientKey = k.APIClientKey
|
||||||
|
}
|
||||||
|
overrides.ClusterInfo = clusterinfo
|
||||||
|
overrides.AuthInfo = authinfo
|
||||||
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
|
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
|
||||||
config, err := clientConfig.ClientConfig()
|
return clientConfig.ClientConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitKubeCache initializes a new Kubernetes cache.
|
||||||
|
// TODO(miek): is this correct?
|
||||||
|
func (k *Kubernetes) InitKubeCache() error {
|
||||||
|
|
||||||
|
config, err := k.getClientConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
kubeClient, err := unversionedclient.New(config)
|
|
||||||
|
|
||||||
|
kubeClient, err := unversionedclient.New(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ERROR] Failed to create kubernetes notification controller: %v", err)
|
log.Printf("[ERROR] Failed to create kubernetes notification controller: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) {
|
|||||||
switch c.Val() {
|
switch c.Val() {
|
||||||
case "template":
|
case "template":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) != 0 {
|
if len(args) > 0 {
|
||||||
template := strings.Join(args, "")
|
template := strings.Join(args, "")
|
||||||
err := k8s.NameTemplate.SetTemplate(template)
|
err := k8s.NameTemplate.SetTemplate(template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -86,21 +86,28 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) {
|
|||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
case "namespaces":
|
case "namespaces":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) != 0 {
|
if len(args) > 0 {
|
||||||
k8s.Namespaces = append(k8s.Namespaces, args...)
|
k8s.Namespaces = append(k8s.Namespaces, args...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) != 0 {
|
if len(args) > 0 {
|
||||||
k8s.APIEndpoint = args[0]
|
k8s.APIEndpoint = args[0]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
|
case "tls": // cert key cacertfile
|
||||||
|
args := c.RemainingArgs()
|
||||||
|
if len(args) == 3 {
|
||||||
|
k8s.APIClientCert, k8s.APIClientKey, k8s.APICertAuth = args[0], args[1], args[2]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, c.ArgErr()
|
||||||
case "resyncperiod":
|
case "resyncperiod":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) != 0 {
|
if len(args) > 0 {
|
||||||
rp, err := time.ParseDuration(args[0])
|
rp, err := time.ParseDuration(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v", args[0], err)
|
return nil, fmt.Errorf("Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v", args[0], err)
|
||||||
@@ -111,7 +118,7 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) {
|
|||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
case "labels":
|
case "labels":
|
||||||
args := c.RemainingArgs()
|
args := c.RemainingArgs()
|
||||||
if len(args) != 0 {
|
if len(args) > 0 {
|
||||||
labelSelectorString := strings.Join(args, " ")
|
labelSelectorString := strings.Join(args, " ")
|
||||||
ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString)
|
ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user