2016-08-19 17:14:17 -07:00
package kubernetes
2016-06-06 12:49:53 -07:00
import (
2016-08-05 18:19:51 -07:00
"errors"
2016-08-08 14:30:04 -07:00
"fmt"
2017-02-01 12:56:10 -05:00
"net"
2016-07-07 01:40:58 -07:00
"strings"
2016-08-05 18:19:51 -07:00
"time"
2016-06-06 12:49:53 -07:00
2016-08-19 17:14:17 -07:00
"github.com/miekg/coredns/core/dnsserver"
2016-06-06 12:49:53 -07:00
"github.com/miekg/coredns/middleware"
2016-08-19 17:14:17 -07:00
"github.com/mholt/caddy"
2016-11-05 07:57:08 -04:00
unversionedapi "k8s.io/client-go/1.5/pkg/api/unversioned"
2016-06-06 12:49:53 -07:00
)
2016-08-19 17:14:17 -07:00
func init ( ) {
caddy . RegisterPlugin ( "kubernetes" , caddy . Plugin {
ServerType : "dns" ,
Action : setup ,
} )
}
2016-06-06 12:49:53 -07:00
2016-08-19 17:14:17 -07:00
func setup ( c * caddy . Controller ) error {
2016-06-06 12:49:53 -07:00
kubernetes , err := kubernetesParse ( c )
2016-08-05 18:19:51 -07:00
if err != nil {
2016-09-10 09:16:25 +01:00
return middleware . Error ( "kubernetes" , err )
2016-08-05 18:19:51 -07:00
}
2016-06-06 12:49:53 -07:00
2016-08-19 17:14:17 -07:00
err = kubernetes . InitKubeCache ( )
2016-06-06 12:49:53 -07:00
if err != nil {
2016-09-10 09:16:25 +01:00
return middleware . Error ( "kubernetes" , err )
2016-06-06 12:49:53 -07:00
}
2016-08-19 17:14:17 -07:00
// Register KubeCache start and stop functions with Caddy
c . OnStartup ( func ( ) error {
go kubernetes . APIConn . Run ( )
return nil
} )
c . OnShutdown ( func ( ) error {
return kubernetes . APIConn . Stop ( )
} )
2016-09-19 11:26:00 +01:00
dnsserver . GetConfig ( c ) . AddMiddleware ( func ( next middleware . Handler ) middleware . Handler {
2016-06-06 12:49:53 -07:00
kubernetes . Next = next
return kubernetes
2016-08-19 17:14:17 -07:00
} )
return nil
2016-06-06 12:49:53 -07:00
}
2016-09-23 11:08:23 -03:00
func kubernetesParse ( c * caddy . Controller ) ( * Kubernetes , error ) {
k8s := & Kubernetes { ResyncPeriod : defaultResyncPeriod }
2017-01-11 16:23:10 -05:00
k8s . PodMode = PodModeDisabled
2016-07-07 01:40:58 -07:00
2016-06-06 12:49:53 -07:00
for c . Next ( ) {
if c . Val ( ) == "kubernetes" {
2016-07-07 01:40:58 -07:00
zones := c . RemainingArgs ( )
if len ( zones ) == 0 {
2016-08-19 17:14:17 -07:00
k8s . Zones = make ( [ ] string , len ( c . ServerBlockKeys ) )
copy ( k8s . Zones , c . ServerBlockKeys )
2016-06-06 12:49:53 -07:00
}
2016-07-07 01:40:58 -07:00
2016-08-19 17:14:17 -07:00
k8s . Zones = NormalizeZoneList ( zones )
2016-09-07 11:10:16 +01:00
middleware . Zones ( k8s . Zones ) . Normalize ( )
2016-08-19 17:14:17 -07:00
2016-08-05 18:19:51 -07:00
if k8s . Zones == nil || len ( k8s . Zones ) < 1 {
2016-09-23 11:08:23 -03:00
return nil , errors . New ( "Zone name must be provided for kubernetes middleware." )
2016-08-05 18:19:51 -07:00
}
2016-07-22 16:07:27 -07:00
2016-11-14 19:31:08 +00:00
k8s . primaryZone = - 1
for i , z := range k8s . Zones {
if strings . HasSuffix ( z , "in-addr.arpa." ) || strings . HasSuffix ( z , "ip6.arpa." ) {
continue
}
k8s . primaryZone = i
break
}
if k8s . primaryZone == - 1 {
return nil , errors . New ( "A non-reverse zone name must be given for Kubernetes." )
}
2016-08-05 18:19:51 -07:00
for c . NextBlock ( ) {
2016-06-06 12:49:53 -07:00
switch c . Val ( ) {
2017-02-01 12:56:10 -05:00
case "cidrs" :
args := c . RemainingArgs ( )
if len ( args ) > 0 {
for _ , cidrStr := range args {
_ , cidr , err := net . ParseCIDR ( cidrStr )
if err != nil {
2017-02-02 16:51:42 -05:00
return nil , errors . New ( "Invalid cidr: " + cidrStr )
2017-02-01 12:56:10 -05:00
}
k8s . ReverseCidrs = append ( k8s . ReverseCidrs , * cidr )
}
continue
}
return nil , c . ArgErr ( )
2017-01-11 16:23:10 -05:00
case "pods" :
args := c . RemainingArgs ( )
if len ( args ) == 1 {
switch args [ 0 ] {
2017-01-20 02:22:11 -05:00
case PodModeDisabled , PodModeInsecure , PodModeVerified :
2017-01-11 16:23:10 -05:00
k8s . PodMode = args [ 0 ]
default :
2017-02-02 16:51:42 -05:00
return nil , errors . New ( "Value for pods must be one of: disabled, verified, insecure" )
2017-01-11 16:23:10 -05:00
}
continue
}
return nil , c . ArgErr ( )
2016-07-22 16:07:27 -07:00
case "namespaces" :
args := c . RemainingArgs ( )
2016-09-23 18:07:06 -04:00
if len ( args ) > 0 {
2016-08-05 18:19:51 -07:00
k8s . Namespaces = append ( k8s . Namespaces , args ... )
2016-09-23 11:08:23 -03:00
continue
2016-07-22 16:07:27 -07:00
}
2016-09-23 11:08:23 -03:00
return nil , c . ArgErr ( )
2016-08-05 18:19:51 -07:00
case "endpoint" :
args := c . RemainingArgs ( )
2016-09-23 18:07:06 -04:00
if len ( args ) > 0 {
2016-08-05 18:19:51 -07:00
k8s . APIEndpoint = args [ 0 ]
2016-09-23 11:08:23 -03:00
continue
2016-06-06 12:49:53 -07:00
}
2016-09-23 11:08:23 -03:00
return nil , c . ArgErr ( )
2016-09-23 18:07:06 -04:00
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 ( )
2016-08-08 14:30:04 -07:00
case "resyncperiod" :
args := c . RemainingArgs ( )
2016-09-23 18:07:06 -04:00
if len ( args ) > 0 {
2016-09-23 11:08:23 -03:00
rp , err := time . ParseDuration ( args [ 0 ] )
2016-08-08 14:30:04 -07:00
if err != nil {
2016-09-23 11:08:23 -03:00
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 )
2016-08-08 14:30:04 -07:00
}
2016-09-23 11:08:23 -03:00
k8s . ResyncPeriod = rp
continue
2016-08-08 14:30:04 -07:00
}
2016-09-23 11:08:23 -03:00
return nil , c . ArgErr ( )
2016-08-12 20:44:08 -07:00
case "labels" :
args := c . RemainingArgs ( )
2016-09-23 18:07:06 -04:00
if len ( args ) > 0 {
2016-08-12 20:44:08 -07:00
labelSelectorString := strings . Join ( args , " " )
2016-09-23 11:08:23 -03:00
ls , err := unversionedapi . ParseToLabelSelector ( labelSelectorString )
2016-08-12 20:44:08 -07:00
if err != nil {
2016-09-23 11:08:23 -03:00
return nil , fmt . Errorf ( "Unable to parse label selector. Value provided was '%v'. Error was: %v" , labelSelectorString , err )
2016-08-12 20:44:08 -07:00
}
2016-09-23 11:08:23 -03:00
k8s . LabelSelector = ls
continue
2016-08-12 20:44:08 -07:00
}
2016-09-23 11:08:23 -03:00
return nil , c . ArgErr ( )
2016-06-06 12:49:53 -07:00
}
}
return k8s , nil
}
}
2016-09-23 11:08:23 -03:00
return nil , errors . New ( "Kubernetes setup called without keyword 'kubernetes' in Corefile" )
2016-06-06 12:49:53 -07:00
}
2016-08-19 17:14:17 -07:00
const (
defaultResyncPeriod = 5 * time . Minute
2017-01-11 16:23:10 -05:00
defaultPodMode = PodModeDisabled
2016-08-19 17:14:17 -07:00
)