2016-06-06 12:49:53 -07:00
package setup
import (
2016-08-05 18:19:51 -07:00
"errors"
2016-08-08 14:30:04 -07:00
"fmt"
2016-07-18 10:47:36 -07:00
"log"
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
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/middleware/kubernetes"
2016-07-07 01:40:58 -07:00
"github.com/miekg/coredns/middleware/kubernetes/nametemplate"
2016-06-06 12:49:53 -07:00
)
2016-07-07 01:40:58 -07:00
const (
defaultNameTemplate = "{service}.{namespace}.{zone}"
2016-08-05 18:19:51 -07:00
defaultResyncPeriod = 5 * time . Minute
2016-07-07 01:40:58 -07:00
)
2016-06-06 12:49:53 -07:00
// Kubernetes sets up the kubernetes middleware.
func Kubernetes ( c * Controller ) ( middleware . Middleware , error ) {
kubernetes , err := kubernetesParse ( c )
2016-08-05 18:19:51 -07:00
if err != nil {
return nil , err
}
2016-06-06 12:49:53 -07:00
2016-08-05 18:19:51 -07:00
err = kubernetes . StartKubeCache ( )
2016-06-06 12:49:53 -07:00
if err != nil {
return nil , err
}
return func ( next middleware . Handler ) middleware . Handler {
kubernetes . Next = next
return kubernetes
} , nil
}
func kubernetesParse ( c * Controller ) ( kubernetes . Kubernetes , error ) {
2016-08-05 18:19:51 -07:00
var err error
template := defaultNameTemplate
2016-06-06 12:49:53 -07:00
k8s := kubernetes . Kubernetes {
2016-08-05 18:19:51 -07:00
ResyncPeriod : defaultResyncPeriod ,
2016-06-06 12:49:53 -07:00
}
2016-07-07 01:40:58 -07:00
k8s . NameTemplate = new ( nametemplate . NameTemplate )
k8s . NameTemplate . SetTemplate ( template )
2016-08-05 18:19:51 -07:00
// TODO: expose resync period in Corefile
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-06-06 12:49:53 -07:00
k8s . Zones = c . ServerBlockHosts
2016-08-05 18:19:51 -07:00
log . Printf ( "[debug] Zones(from ServerBlockHosts): %v" , zones )
2016-07-07 01:40:58 -07:00
} else {
// Normalize requested zones
k8s . Zones = kubernetes . NormalizeZoneList ( zones )
2016-06-06 12:49:53 -07:00
}
2016-07-07 01:40:58 -07:00
2016-06-06 12:49:53 -07:00
middleware . Zones ( k8s . Zones ) . FullyQualify ( )
2016-08-05 18:19:51 -07:00
if k8s . Zones == nil || len ( k8s . Zones ) < 1 {
err = errors . New ( "Zone name must be provided for kubernetes middleware." )
log . Printf ( "[debug] %v\n" , err )
return kubernetes . Kubernetes { } , err
}
2016-07-22 16:07:27 -07:00
2016-08-05 18:19:51 -07:00
for c . NextBlock ( ) {
2016-06-06 12:49:53 -07:00
switch c . Val ( ) {
2016-08-05 18:19:51 -07:00
case "template" :
2016-06-06 12:49:53 -07:00
args := c . RemainingArgs ( )
2016-08-05 18:19:51 -07:00
if len ( args ) != 0 {
template := strings . Join ( args , "" )
err = k8s . NameTemplate . SetTemplate ( template )
if err != nil {
return kubernetes . Kubernetes { } , err
}
} else {
log . Printf ( "[debug] 'template' keyword provided without any template value." )
2016-06-06 12:49:53 -07:00
return kubernetes . Kubernetes { } , c . ArgErr ( )
}
2016-07-22 16:07:27 -07:00
case "namespaces" :
args := c . RemainingArgs ( )
2016-08-05 18:19:51 -07:00
if len ( args ) != 0 {
k8s . Namespaces = append ( k8s . Namespaces , args ... )
} else {
log . Printf ( "[debug] 'namespaces' keyword provided without any namespace values." )
2016-07-22 16:07:27 -07:00
return kubernetes . Kubernetes { } , c . ArgErr ( )
}
2016-08-05 18:19:51 -07:00
case "endpoint" :
args := c . RemainingArgs ( )
if len ( args ) != 0 {
k8s . APIEndpoint = args [ 0 ]
} else {
log . Printf ( "[debug] 'endpoint' keyword provided without any endpoint url value." )
return kubernetes . Kubernetes { } , c . ArgErr ( )
2016-06-06 12:49:53 -07:00
}
2016-08-08 14:30:04 -07:00
case "resyncperiod" :
args := c . RemainingArgs ( )
if len ( args ) != 0 {
k8s . ResyncPeriod , err = time . ParseDuration ( args [ 0 ] )
if err != nil {
err = errors . New ( fmt . Sprintf ( "Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v" , args [ 0 ] , err ) )
log . Printf ( "[ERROR] %v" , err )
return kubernetes . Kubernetes { } , err
}
} else {
log . Printf ( "[debug] 'resyncperiod' keyword provided without any duration value." )
return kubernetes . Kubernetes { } , c . ArgErr ( )
}
2016-06-06 12:49:53 -07:00
}
}
return k8s , nil
}
}
2016-08-05 18:19:51 -07:00
err = errors . New ( "Kubernetes setup called without keyword 'kubernetes' in Corefile" )
log . Printf ( "[ERROR] %v\n" , err )
return kubernetes . Kubernetes { } , err
2016-06-06 12:49:53 -07:00
}