kubenetworks/kubevpn

View on GitHub
pkg/util/dns.go

Summary

Maintainability
A
0 mins
Test Coverage
package util

import (
    "bytes"
    "context"
    "fmt"

    "github.com/miekg/dns"
    "github.com/pkg/errors"
    "k8s.io/api/core/v1"
    v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/fields"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"

    "github.com/wencaiwulue/kubevpn/v2/pkg/config"
)

func GetDNSServiceIPFromPod(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, podName, namespace string) (*dns.ClientConfig, error) {
    str, err := Shell(ctx, clientset, config, podName, "", namespace, []string{"cat", "/etc/resolv.conf"})
    if err != nil {
        return nil, err
    }
    resolvConf, err := dns.ClientConfigFromReader(bytes.NewBufferString(str))
    if err == nil {
        return resolvConf, nil
    }

    ips, err := GetDNSIPFromDnsPod(ctx, clientset)
    if err != nil {
        return nil, err
    }
    clientConfig := dns.ClientConfig{
        Servers: ips,
        Search: []string{
            fmt.Sprintf("%s.svc.cluster.local", namespace),
            "svc.cluster.local",
            "cluster.local",
        },
        Ndots: 5,
    }
    return &clientConfig, nil
}

func GetDNSIPFromDnsPod(ctx context.Context, clientset *kubernetes.Clientset) (ips []string, err error) {
    var serviceList *v1.ServiceList
    serviceList, err = clientset.CoreV1().Services(v12.NamespaceSystem).List(ctx, v12.ListOptions{
        LabelSelector: fields.OneTermEqualSelector("k8s-app", "kube-dns").String(),
    })
    if err != nil {
        return
    }
    for _, item := range serviceList.Items {
        if len(item.Spec.ClusterIP) != 0 {
            ips = append(ips, item.Spec.ClusterIP)
        }
    }
    var podList *v1.PodList
    podList, err = clientset.CoreV1().Pods(v12.NamespaceSystem).List(ctx, v12.ListOptions{
        LabelSelector: fields.OneTermEqualSelector("k8s-app", "kube-dns").String(),
    })
    if err == nil {
        for _, pod := range podList.Items {
            if pod.Status.Phase == v1.PodRunning && pod.DeletionTimestamp == nil {
                ips = append(ips, pod.Status.PodIP)
            }
        }
    }
    if len(ips) == 0 {
        err = errors.New("can not found any DNS service IP")
        return
    }
    err = nil
    return
}

func GetDNS(ctx context.Context, clientSet *kubernetes.Clientset, restConfig *rest.Config, ns, pod string) (*dns.ClientConfig, error) {
    _, err := clientSet.CoreV1().Pods(ns).Get(ctx, pod, v12.GetOptions{})
    if err != nil {
        return nil, err
    }
    clientConfig, err := GetDNSServiceIPFromPod(ctx, clientSet, restConfig, pod, ns)
    if err != nil {
        return nil, err
    }
    svc, err := clientSet.CoreV1().Services(ns).Get(ctx, config.ConfigMapPodTrafficManager, v12.GetOptions{})
    if err != nil {
        return nil, err
    }
    clientConfig.Servers = []string{svc.Spec.ClusterIP}
    return clientConfig, nil
}