2016-08-19 17:14:17 -07:00
package kubernetes
2016-07-22 16:07:27 -07:00
import (
2017-02-02 16:51:42 -05:00
"net"
2016-07-22 16:07:27 -07:00
"strings"
"testing"
2016-08-08 14:30:04 -07:00
"time"
2016-08-12 20:44:08 -07:00
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-07-22 16:07:27 -07:00
)
2017-02-02 16:51:42 -05:00
func parseCidr ( cidr string ) net . IPNet {
_ , ipnet , _ := net . ParseCIDR ( cidr )
return * ipnet
}
2016-07-22 16:07:27 -07:00
func TestKubernetesParse ( t * testing . T ) {
tests := [ ] struct {
2016-08-12 20:44:08 -07:00
description string // Human-facing description of test case
input string // Corefile data as string
shouldErr bool // true if test case is exected to produce an error.
expectedErrContent string // substring from the expected error. Empty for positive cases.
expectedZoneCount int // expected count of defined zones.
expectedNSCount int // expected count of namespaces.
expectedResyncPeriod time . Duration // expected resync period value
expectedLabelSelector string // expected label selector value
2017-02-02 16:51:42 -05:00
expectedPodMode string
expectedCidrs [ ] net . IPNet
2016-07-22 16:07:27 -07:00
} {
// positive
{
2016-08-05 18:19:51 -07:00
"kubernetes keyword with one zone" ,
` kubernetes coredns.local ` ,
2016-07-22 16:07:27 -07:00
false ,
"" ,
2016-08-05 18:19:51 -07:00
1 ,
2016-07-22 16:07:27 -07:00
0 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
{
2016-08-05 18:19:51 -07:00
"kubernetes keyword with multiple zones" ,
` kubernetes coredns.local test.local ` ,
2016-07-22 16:07:27 -07:00
false ,
"" ,
2016-08-05 18:19:51 -07:00
2 ,
2016-07-22 16:07:27 -07:00
0 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
{
2016-08-05 18:19:51 -07:00
"kubernetes keyword with zone and empty braces" ,
` kubernetes coredns . local {
} ` ,
2016-07-22 16:07:27 -07:00
false ,
"" ,
2016-08-05 18:19:51 -07:00
1 ,
2016-07-22 16:07:27 -07:00
0 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
{
2016-08-05 18:19:51 -07:00
"endpoint keyword with url" ,
2016-07-22 16:07:27 -07:00
` kubernetes coredns . local {
2016-08-05 18:19:51 -07:00
endpoint http : //localhost:9090
2016-07-22 16:07:27 -07:00
} ` ,
false ,
"" ,
1 ,
0 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
{
2016-08-05 18:19:51 -07:00
"namespaces keyword with one namespace" ,
2016-07-22 16:07:27 -07:00
` kubernetes coredns . local {
namespaces demo
} ` ,
false ,
"" ,
1 ,
1 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
{
2016-08-05 18:19:51 -07:00
"namespaces keyword with multiple namespaces" ,
2016-07-22 16:07:27 -07:00
` kubernetes coredns . local {
namespaces demo test
} ` ,
false ,
"" ,
1 ,
2 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-08 14:30:04 -07:00
} ,
{
"resync period in seconds" ,
` kubernetes coredns . local {
resyncperiod 30 s
} ` ,
false ,
"" ,
1 ,
0 ,
30 * time . Second ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-08 14:30:04 -07:00
} ,
{
"resync period in minutes" ,
` kubernetes coredns . local {
resyncperiod 15 m
} ` ,
false ,
"" ,
1 ,
0 ,
15 * time . Minute ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-12 20:44:08 -07:00
} ,
{
"basic label selector" ,
` kubernetes coredns . local {
labels environment = prod
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"environment=prod" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-12 20:44:08 -07:00
} ,
{
"multi-label selector" ,
` kubernetes coredns . local {
labels environment in ( production , staging , qa ) , application = nginx
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"application=nginx,environment in (production,qa,staging)" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
2016-08-05 18:19:51 -07:00
{
"fully specified valid config" ,
` kubernetes coredns . local test . local {
2016-08-08 14:30:04 -07:00
resyncperiod 15 m
2016-08-05 18:19:51 -07:00
endpoint http : //localhost:8080
namespaces demo test
2016-08-12 20:44:08 -07:00
labels environment in ( production , staging , qa ) , application = nginx
2016-08-05 18:19:51 -07:00
} ` ,
false ,
"" ,
2 ,
2 ,
2016-08-08 14:30:04 -07:00
15 * time . Minute ,
2016-08-12 20:44:08 -07:00
"application=nginx,environment in (production,qa,staging)" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-05 18:19:51 -07:00
} ,
2016-07-22 16:07:27 -07:00
// negative
{
2016-08-05 18:19:51 -07:00
"no kubernetes keyword" ,
"" ,
true ,
"Kubernetes setup called without keyword 'kubernetes' in Corefile" ,
- 1 ,
- 1 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-05 18:19:51 -07:00
} ,
{
"kubernetes keyword without a zone" ,
` kubernetes ` ,
true ,
2017-02-22 09:23:41 +00:00
"zone name must be provided for kubernetes middleware" ,
2016-08-05 18:19:51 -07:00
- 1 ,
0 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-05 18:19:51 -07:00
} ,
{
"endpoint keyword without an endpoint value" ,
2016-07-22 16:07:27 -07:00
` kubernetes coredns . local {
endpoint
} ` ,
true ,
"Wrong argument count or unexpected line ending after 'endpoint'" ,
- 1 ,
- 1 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-05 18:19:51 -07:00
} ,
{
"namespace keyword without a namespace value" ,
` kubernetes coredns . local {
namespaces
} ` ,
true ,
"Parse error: Wrong argument count or unexpected line ending after 'namespaces'" ,
- 1 ,
2016-07-22 16:07:27 -07:00
- 1 ,
2016-08-08 14:30:04 -07:00
defaultResyncPeriod ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-08 14:30:04 -07:00
} ,
{
"resyncperiod keyword without a duration value" ,
` kubernetes coredns . local {
resyncperiod
} ` ,
true ,
"Wrong argument count or unexpected line ending after 'resyncperiod'" ,
- 1 ,
0 ,
0 * time . Minute ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-08 14:30:04 -07:00
} ,
{
"resync period no units" ,
` kubernetes coredns . local {
resyncperiod 15
} ` ,
true ,
"Unable to parse resync duration value. Value provided was " ,
- 1 ,
0 ,
0 * time . Second ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-08 14:30:04 -07:00
} ,
{
"resync period invalid" ,
` kubernetes coredns . local {
resyncperiod abc
} ` ,
true ,
"Unable to parse resync duration value. Value provided was " ,
- 1 ,
0 ,
0 * time . Second ,
2016-08-12 20:44:08 -07:00
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-12 20:44:08 -07:00
} ,
{
"labels with no selector value" ,
` kubernetes coredns . local {
labels
} ` ,
true ,
"Wrong argument count or unexpected line ending after 'labels'" ,
- 1 ,
0 ,
0 * time . Second ,
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
2016-08-12 20:44:08 -07:00
} ,
{
"labels with invalid selector value" ,
` kubernetes coredns . local {
labels environment in ( production , qa
} ` ,
true ,
"Unable to parse label selector. Value provided was" ,
- 1 ,
0 ,
0 * time . Second ,
"" ,
2017-02-02 16:51:42 -05:00
defaultPodMode ,
nil ,
} ,
// pods disabled
{
"pods disabled" ,
` kubernetes coredns . local {
pods disabled
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"" ,
PodModeDisabled ,
nil ,
} ,
// pods insecure
{
"pods insecure" ,
` kubernetes coredns . local {
pods insecure
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"" ,
PodModeInsecure ,
nil ,
} ,
// pods verified
{
"pods verified" ,
` kubernetes coredns . local {
pods verified
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"" ,
PodModeVerified ,
nil ,
} ,
// pods invalid
{
"invalid pods mode" ,
` kubernetes coredns . local {
pods giant_seed
} ` ,
true ,
"Value for pods must be one of: disabled, verified, insecure" ,
- 1 ,
0 ,
defaultResyncPeriod ,
"" ,
PodModeVerified ,
nil ,
} ,
// cidrs ok
{
"valid cidrs" ,
` kubernetes coredns . local {
cidrs 10.0 .0 .0 / 24 10.0 .1 .0 / 24
} ` ,
false ,
"" ,
1 ,
0 ,
defaultResyncPeriod ,
"" ,
defaultPodMode ,
[ ] net . IPNet { parseCidr ( "10.0.0.0/24" ) , parseCidr ( "10.0.1.0/24" ) } ,
} ,
// cidrs ok
{
"Invalid cidr: hard" ,
` kubernetes coredns . local {
cidrs hard dry
} ` ,
true ,
"Invalid cidr: hard" ,
- 1 ,
0 ,
defaultResyncPeriod ,
"" ,
defaultPodMode ,
nil ,
2016-07-22 16:07:27 -07:00
} ,
}
for i , test := range tests {
2016-08-19 17:14:17 -07:00
c := caddy . NewTestController ( "dns" , test . input )
2016-07-22 16:07:27 -07:00
k8sController , err := kubernetesParse ( c )
if test . shouldErr && err == nil {
2016-08-05 18:19:51 -07:00
t . Errorf ( "Test %d: Expected error, but did not find error for input '%s'. Error was: '%v'" , i , test . input , err )
2016-07-22 16:07:27 -07:00
}
if err != nil {
if ! test . shouldErr {
t . Errorf ( "Test %d: Expected no error but found one for input %s. Error was: %v" , i , test . input , err )
2016-08-05 18:19:51 -07:00
continue
2016-07-22 16:07:27 -07:00
}
if test . shouldErr && ( len ( test . expectedErrContent ) < 1 ) {
t . Fatalf ( "Test %d: Test marked as expecting an error, but no expectedErrContent provided for input '%s'. Error was: '%v'" , i , test . input , err )
}
if test . shouldErr && ( test . expectedZoneCount >= 0 ) {
2016-08-05 18:19:51 -07:00
t . Errorf ( "Test %d: Test marked as expecting an error, but provides value for expectedZoneCount!=-1 for input '%s'. Error was: '%v'" , i , test . input , err )
2016-07-22 16:07:27 -07:00
}
if ! strings . Contains ( err . Error ( ) , test . expectedErrContent ) {
t . Errorf ( "Test %d: Expected error to contain: %v, found error: %v, input: %s" , i , test . expectedErrContent , err , test . input )
}
2016-08-05 18:19:51 -07:00
continue
2016-07-22 16:07:27 -07:00
}
// No error was raised, so validate initialization of k8sController
// Zones
foundZoneCount := len ( k8sController . Zones )
if foundZoneCount != test . expectedZoneCount {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with %d zones, instead found %d zones: '%v' for input '%s'" , i , test . expectedZoneCount , foundZoneCount , k8sController . Zones , test . input )
}
// Namespaces
foundNSCount := len ( k8sController . Namespaces )
if foundNSCount != test . expectedNSCount {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with %d namespaces. Instead found %d namespaces: '%v' for input '%s'" , i , test . expectedNSCount , foundNSCount , k8sController . Namespaces , test . input )
2016-08-08 14:30:04 -07:00
}
// ResyncPeriod
foundResyncPeriod := k8sController . ResyncPeriod
if foundResyncPeriod != test . expectedResyncPeriod {
2016-08-12 20:44:08 -07:00
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with resync period '%s'. Instead found period '%s' for input '%s'" , i , test . expectedResyncPeriod , foundResyncPeriod , test . input )
}
// Labels
if k8sController . LabelSelector != nil {
foundLabelSelectorString := unversionedapi . FormatLabelSelector ( k8sController . LabelSelector )
if foundLabelSelectorString != test . expectedLabelSelector {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with label selector '%s'. Instead found selector '%s' for input '%s'" , i , test . expectedLabelSelector , foundLabelSelectorString , test . input )
}
2016-07-22 16:07:27 -07:00
}
2017-02-02 16:51:42 -05:00
// Pods
foundPodMode := k8sController . PodMode
if foundPodMode != test . expectedPodMode {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with pod mode '%s'. Instead found pod mode '%s' for input '%s'" , i , test . expectedPodMode , foundPodMode , test . input )
}
// Cidrs
foundCidrs := k8sController . ReverseCidrs
if len ( foundCidrs ) != len ( test . expectedCidrs ) {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with %d cidrs. Instead found %d cidrs for input '%s'" , i , len ( test . expectedCidrs ) , len ( foundCidrs ) , test . input )
}
for j , cidr := range test . expectedCidrs {
if cidr . String ( ) != foundCidrs [ j ] . String ( ) {
t . Errorf ( "Test %d: Expected kubernetes controller to be initialized with cidr '%s'. Instead found cidr '%s' for input '%s'" , i , test . expectedCidrs [ j ] . String ( ) , foundCidrs [ j ] . String ( ) , test . input )
}
}
2016-07-22 16:07:27 -07:00
}
}