aboutsummaryrefslogtreecommitdiff
path: root/middleware/kubernetes/kubernetes.go
diff options
context:
space:
mode:
authorGravatar Chris O'Haver <cohaver@infoblox.com> 2017-01-11 16:23:10 -0500
committerGravatar Miek Gieben <miek@miek.nl> 2017-01-11 21:23:10 +0000
commit0ee88d300794a9c77d96c57097b72743758e8bd4 (patch)
tree0b644d44da92d08f255a364cb49c82e3ddb1d31f /middleware/kubernetes/kubernetes.go
parentb10a4f90758cb2640c35b84536c0993bb607e9b4 (diff)
downloadcoredns-0ee88d300794a9c77d96c57097b72743758e8bd4.tar.gz
coredns-0ee88d300794a9c77d96c57097b72743758e8bd4.tar.zst
coredns-0ee88d300794a9c77d96c57097b72743758e8bd4.zip
Add insecure A records for pods (#475)
Diffstat (limited to 'middleware/kubernetes/kubernetes.go')
-rw-r--r--middleware/kubernetes/kubernetes.go82
1 files changed, 66 insertions, 16 deletions
diff --git a/middleware/kubernetes/kubernetes.go b/middleware/kubernetes/kubernetes.go
index 68086702e..85e4940ac 100644
--- a/middleware/kubernetes/kubernetes.go
+++ b/middleware/kubernetes/kubernetes.go
@@ -42,8 +42,14 @@ type Kubernetes struct {
Namespaces []string
LabelSelector *unversionedapi.LabelSelector
Selector *labels.Selector
+ PodMode string
}
+const (
+ PodModeDisabled = "disabled" // default. pod requests are ignored
+ PodModeInsecure = "insecure" // ALL pod requests are answered without verfying they exist
+)
+
type endpoint struct {
addr api.EndpointAddress
port api.EndpointPort
@@ -57,6 +63,12 @@ type service struct {
endpoints []endpoint
}
+type pod struct {
+ name string
+ namespace string
+ addr string
+}
+
var errNoItems = errors.New("no items found")
var errNsNotExposed = errors.New("namespace is not exposed")
var errInvalidRequest = errors.New("invalid query name")
@@ -221,12 +233,9 @@ func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) {
return nil, errNoItems
}
- // TODO: Implementation above globbed together segments for the serviceName if
- // multiple segments remained. Determine how to do similar globbing using
- // the template-based implementation.
- namespace = k.NameTemplate.NamespaceFromSegmentArray(serviceSegments)
- serviceName = k.NameTemplate.ServiceFromSegmentArray(serviceSegments)
- typeName = k.NameTemplate.TypeFromSegmentArray(serviceSegments)
+ serviceName = serviceSegments[0]
+ namespace = serviceSegments[1]
+ typeName = serviceSegments[2]
if namespace == "" {
err := errors.New("Parsing query string did not produce a namespace value. Assuming wildcard namespace.")
@@ -246,16 +255,16 @@ func (k *Kubernetes) Records(name string, exact bool) ([]msg.Service, error) {
return nil, errNsNotExposed
}
- k8sItems, err := k.Get(namespace, serviceName, endpointname, port, protocol, typeName)
+ services, pods, err := k.Get(namespace, serviceName, endpointname, port, protocol, typeName)
if err != nil {
return nil, err
}
- if len(k8sItems) == 0 {
+ if len(services) == 0 && len(pods) == 0 {
// Did not find item in k8s
return nil, errNoItems
}
- records := k.getRecordsForServiceItems(k8sItems, zone)
+ records := k.getRecordsForK8sItems(services, pods, zone)
return records, nil
}
@@ -272,10 +281,10 @@ func endpointHostname(addr api.EndpointAddress) string {
return ""
}
-func (k *Kubernetes) getRecordsForServiceItems(serviceItems []service, zone string) []msg.Service {
+func (k *Kubernetes) getRecordsForK8sItems(services []service, pods []pod, zone string) []msg.Service {
var records []msg.Service
- for _, svc := range serviceItems {
+ for _, svc := range services {
key := svc.name + "." + svc.namespace + ".svc." + zone
@@ -299,20 +308,61 @@ func (k *Kubernetes) getRecordsForServiceItems(serviceItems []service, zone stri
}
}
+ for _, p := range pods {
+ key := p.name + "." + p.namespace + ".pod." + zone
+ s := msg.Service{
+ Key: msg.Path(strings.ToLower(key), "coredns"),
+ Host: p.addr,
+ }
+ records = append(records, s)
+ }
+
return records
}
-// Get performs the call to the Kubernetes http API.
-func (k *Kubernetes) Get(namespace, servicename, endpointname, port, protocol, typeName string) (services []service, err error) {
+// Get retrieves matching data from the cache.
+func (k *Kubernetes) Get(namespace, servicename, endpointname, port, protocol, typeName string) (services []service, pods []pod, err error) {
switch {
case typeName == "pod":
- return nil, fmt.Errorf("%v not implemented", typeName)
+ pods, err = k.findPods(namespace, servicename)
+ return nil, pods, err
default:
- return k.getServices(namespace, servicename, endpointname, port, protocol)
+ services, err = k.findServices(namespace, servicename, endpointname, port, protocol)
+ return services, nil, err
}
}
-func (k *Kubernetes) getServices(namespace, servicename, endpointname, port, protocol string) ([]service, error) {
+func ipFromPodName(podname string) string {
+ if strings.Count(podname, "-") == 3 && !strings.Contains(podname, "--") {
+ return strings.Replace(podname, "-", ".", -1)
+ }
+ return strings.Replace(podname, "-", ":", -1)
+}
+
+func (k *Kubernetes) findPods(namespace, podname string) (pods []pod, err error) {
+ if k.PodMode == PodModeDisabled {
+ return pods, nil
+ }
+
+ var ip string
+ if strings.Count(podname, "-") == 3 && !strings.Contains(podname, "--") {
+ ip = strings.Replace(podname, "-", ".", -1)
+ } else {
+ ip = strings.Replace(podname, "-", ":", -1)
+ }
+
+ if k.PodMode == PodModeInsecure {
+ s := pod{name: podname, namespace: namespace, addr: ip}
+ pods = append(pods, s)
+ return pods, nil
+ }
+
+ // TODO: implement cache verified pod responses
+ return pods, nil
+
+}
+
+func (k *Kubernetes) findServices(namespace, servicename, endpointname, port, protocol string) ([]service, error) {
serviceList := k.APIConn.ServiceList()
var resultItems []service