diff options
author | 2016-09-23 18:07:06 -0400 | |
---|---|---|
committer | 2016-09-23 23:07:06 +0100 | |
commit | 15297c8e637927500902e848ac73bd510cd4c49e (patch) | |
tree | 4efd9c10e84a255821ddf09bb65c1f2839ab59d0 | |
parent | b9cf32f7a9e02492927263f3f7f1281ffc112255 (diff) | |
download | coredns-15297c8e637927500902e848ac73bd510cd4c49e.tar.gz coredns-15297c8e637927500902e848ac73bd510cd4c49e.tar.zst coredns-15297c8e637927500902e848ac73bd510cd4c49e.zip |
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
-rw-r--r-- | middleware/kubernetes/README.md | 4 | ||||
-rw-r--r-- | middleware/kubernetes/kubernetes.go | 34 | ||||
-rw-r--r-- | middleware/kubernetes/setup.go | 17 |
3 files changed, 43 insertions, 12 deletions
diff --git a/middleware/kubernetes/README.md b/middleware/kubernetes/README.md index 19fb47700..0324cebfa 100644 --- a/middleware/kubernetes/README.md +++ b/middleware/kubernetes/README.md @@ -40,7 +40,9 @@ This is the default kubernetes setup, with everything specified in full: # Example values: 60s, 5m, 1h resyncperiod 5m # 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 template {service}.{namespace}.{zone} # Only expose the k8s namespace "demo" diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go index ae57c6e98..3f8b539c7 100644 --- a/middleware/kubernetes/kubernetes.go +++ b/middleware/kubernetes/kubernetes.go @@ -18,6 +18,7 @@ import ( "k8s.io/kubernetes/pkg/api" unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" unversionedclient "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" "k8s.io/kubernetes/pkg/labels" @@ -29,6 +30,9 @@ type Kubernetes struct { Zones []string Proxy proxy.Proxy // Proxy for looking up names during the resolution process APIEndpoint string + APICertAuth string + APIClientCert string + APIClientKey string APIConn *dnsController ResyncPeriod time.Duration NameTemplate *nametemplate.NameTemplate @@ -37,23 +41,41 @@ type Kubernetes struct { Selector *labels.Selector } -// InitKubeCache initializes a new Kubernetes cache. -// TODO(miek): is this correct? -func (k *Kubernetes) InitKubeCache() error { +func (k *Kubernetes) getClientConfig() (*restclient.Config, error) { // For a custom api server or running outside a k8s cluster // set URL in env.KUBERNETES_MASTER or set endpoint in Corefile loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() overrides := &clientcmd.ConfigOverrides{} + clusterinfo := clientcmdapi.Cluster{} + authinfo := clientcmdapi.AuthInfo{} 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) - 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 { return err } - kubeClient, err := unversionedclient.New(config) + kubeClient, err := unversionedclient.New(config) if err != nil { log.Printf("[ERROR] Failed to create kubernetes notification controller: %v", err) return err diff --git a/middleware/kubernetes/setup.go b/middleware/kubernetes/setup.go index 51af9ac9d..7b5912dd6 100644 --- a/middleware/kubernetes/setup.go +++ b/middleware/kubernetes/setup.go @@ -75,7 +75,7 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { switch c.Val() { case "template": args := c.RemainingArgs() - if len(args) != 0 { + if len(args) > 0 { template := strings.Join(args, "") err := k8s.NameTemplate.SetTemplate(template) if err != nil { @@ -86,21 +86,28 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { return nil, c.ArgErr() case "namespaces": args := c.RemainingArgs() - if len(args) != 0 { + if len(args) > 0 { k8s.Namespaces = append(k8s.Namespaces, args...) continue } return nil, c.ArgErr() case "endpoint": args := c.RemainingArgs() - if len(args) != 0 { + if len(args) > 0 { k8s.APIEndpoint = args[0] continue } 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": args := c.RemainingArgs() - if len(args) != 0 { + if len(args) > 0 { rp, err := time.ParseDuration(args[0]) 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) @@ -111,7 +118,7 @@ func kubernetesParse(c *caddy.Controller) (*Kubernetes, error) { return nil, c.ArgErr() case "labels": args := c.RemainingArgs() - if len(args) != 0 { + if len(args) > 0 { labelSelectorString := strings.Join(args, " ") ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString) if err != nil { |