Merge pull request #116800 from claudiubelu/windows-remove-dns-check

kubelet: Read DNS Config options from file for Windows
This commit is contained in:
Kubernetes Prow Robot 2023-03-21 16:36:00 -07:00 committed by GitHub
commit b2b9395c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 93 deletions

View File

@ -281,6 +281,33 @@ func parseResolvConf(reader io.Reader) (nameservers []string, searches []string,
return nameservers, searches, options, utilerrors.NewAggregate(allErrors) return nameservers, searches, options, utilerrors.NewAggregate(allErrors)
} }
// Reads a resolv.conf-like file and returns the DNS config options from it.
// Returns an empty DNSConfig if the given resolverConfigFile is an empty string.
func getDNSConfig(resolverConfigFile string) (*runtimeapi.DNSConfig, error) {
var hostDNS, hostSearch, hostOptions []string
// Get host DNS settings
if resolverConfigFile != "" {
f, err := os.Open(resolverConfigFile)
if err != nil {
klog.ErrorS(err, "Could not open resolv conf file.")
return nil, err
}
defer f.Close()
hostDNS, hostSearch, hostOptions, err = parseResolvConf(f)
if err != nil {
err := fmt.Errorf("Encountered error while parsing resolv conf file. Error: %w", err)
klog.ErrorS(err, "Could not parse resolv conf file.")
return nil, err
}
}
return &runtimeapi.DNSConfig{
Servers: hostDNS,
Searches: hostSearch,
Options: hostOptions,
}, nil
}
func getPodDNSType(pod *v1.Pod) (podDNSType, error) { func getPodDNSType(pod *v1.Pod) (podDNSType, error) {
dnsPolicy := pod.Spec.DNSPolicy dnsPolicy := pod.Spec.DNSPolicy
switch dnsPolicy { switch dnsPolicy {

View File

@ -19,35 +19,5 @@ limitations under the License.
package dns package dns
import ( // Read the DNS configuration from a resolv.conf file.
"fmt" var getHostDNSConfig = getDNSConfig
"os"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
"k8s.io/klog/v2"
)
func getHostDNSConfig(resolverConfig string) (*runtimeapi.DNSConfig, error) {
var hostDNS, hostSearch, hostOptions []string
// Get host DNS settings
if resolverConfig != "" {
f, err := os.Open(resolverConfig)
if err != nil {
klog.ErrorS(err, "Could not open resolv conf file.")
return nil, err
}
defer f.Close()
hostDNS, hostSearch, hostOptions, err = parseResolvConf(f)
if err != nil {
err := fmt.Errorf("Encountered error while parsing resolv conf file. Error: %w", err)
klog.ErrorS(err, "Could not parse resolv conf file.")
return nil, err
}
}
return &runtimeapi.DNSConfig{
Servers: hostDNS,
Searches: hostSearch,
Options: hostOptions,
}, nil
}

View File

@ -19,39 +19,8 @@ limitations under the License.
package dns package dns
import (
"fmt"
"os"
"testing"
)
var ( var (
defaultResolvConf = "/etc/resolv.conf" defaultResolvConf = "/etc/resolv.conf"
// configurer.getHostDNSConfig is faked on Windows, while it is not faked on Linux. // configurer.getHostDNSConfig is faked on Windows, while it is not faked on Linux.
fakeGetHostDNSConfigCustom = getHostDNSConfig fakeGetHostDNSConfigCustom = getHostDNSConfig
) )
// getResolvConf returns a temporary resolv.conf file containing the testHostNameserver nameserver and
// testHostDomain search field, and a cleanup function for the temporary file.
func getResolvConf(t *testing.T) (string, func()) {
resolvConfContent := []byte(fmt.Sprintf("nameserver %s\nsearch %s\n", testHostNameserver, testHostDomain))
tmpfile, err := os.CreateTemp("", "tmpResolvConf")
if err != nil {
t.Fatal(err)
}
cleanup := func() {
os.Remove(tmpfile.Name())
}
if _, err := tmpfile.Write(resolvConfContent); err != nil {
cleanup()
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
cleanup()
t.Fatal(err)
}
return tmpfile.Name(), cleanup
}

View File

@ -19,6 +19,7 @@ package dns
import ( import (
"fmt" "fmt"
"net" "net"
"os"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -536,6 +537,7 @@ func testGetPodDNS(t *testing.T) {
} }
configurer = NewConfigurer(recorder, nodeRef, nil, testClusterDNS, testClusterDNSDomain, defaultResolvConf) configurer = NewConfigurer(recorder, nodeRef, nil, testClusterDNS, testClusterDNSDomain, defaultResolvConf)
configurer.getHostDNSConfig = fakeGetHostDNSConfigCustom
for i, pod := range pods { for i, pod := range pods {
var err error var err error
dnsConfig, err := configurer.GetPodDNS(pod) dnsConfig, err := configurer.GetPodDNS(pod)
@ -600,11 +602,20 @@ func TestGetPodDNSCustom(t *testing.T) {
}, },
} }
resolvConf, cleanup := getResolvConf(t) resolvConfContent := []byte(fmt.Sprintf("nameserver %s\nsearch %s\n", testHostNameserver, testHostDomain))
defer cleanup() tmpfile, err := os.CreateTemp("", "tmpResolvConf")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
if _, err := tmpfile.Write(resolvConfContent); err != nil {
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}
configurer := NewConfigurer(recorder, nodeRef, nil, []net.IP{netutils.ParseIPSloppy(testClusterNameserver)}, testClusterDNSDomain, resolvConf) configurer := NewConfigurer(recorder, nodeRef, nil, []net.IP{netutils.ParseIPSloppy(testClusterNameserver)}, testClusterDNSDomain, tmpfile.Name())
configurer.getHostDNSConfig = fakeGetHostDNSConfigCustom
testCases := []struct { testCases := []struct {
desc string desc string

View File

@ -21,6 +21,7 @@ package dns
import ( import (
"fmt" "fmt"
"os"
"strings" "strings"
"syscall" "syscall"
"unsafe" "unsafe"
@ -63,31 +64,55 @@ var (
procGetNetworkParams = iphlpapidll.MustFindProc("GetNetworkParams") procGetNetworkParams = iphlpapidll.MustFindProc("GetNetworkParams")
) )
func fileExists(filename string) (bool, error) {
stat, err := os.Stat(filename)
if os.IsNotExist(err) {
return false, nil
}
if err != nil {
return false, err
}
return stat.Mode().IsRegular(), nil
}
func getHostDNSConfig(resolverConfig string) (*runtimeapi.DNSConfig, error) { func getHostDNSConfig(resolverConfig string) (*runtimeapi.DNSConfig, error) {
if resolverConfig != "" && resolverConfig != hostResolvConf { if resolverConfig == "" {
err := fmt.Errorf(`Unexpected resolver config value: "%s". Expected "" or "%s".`, resolverConfig, hostResolvConf) // This handles "" by returning defaults.
return getDNSConfig(resolverConfig)
}
isFile, err := fileExists(resolverConfig)
if err != nil {
err = fmt.Errorf(`Unexpected error while getting os.Stat for "%s" resolver config. Error: %w`, resolverConfig, err)
klog.ErrorS(err, "Cannot get host DNS Configuration.")
return nil, err
}
if isFile {
// Get the DNS config from a resolv.conf-like file.
return getDNSConfig(resolverConfig)
}
if resolverConfig != hostResolvConf {
err := fmt.Errorf(`Unexpected resolver config value: "%s". Expected "", "%s", or a path to an existing resolv.conf file.`, resolverConfig, hostResolvConf)
klog.ErrorS(err, "Cannot get host DNS Configuration.") klog.ErrorS(err, "Cannot get host DNS Configuration.")
return nil, err return nil, err
} }
var ( // If we get here, the resolverConfig == hostResolvConf and that is not actually a file, so
hostDNS, hostSearch []string // it means to use the host settings.
err error
)
// Get host DNS settings // Get host DNS settings
if resolverConfig == hostResolvConf { hostDNS, err := getDNSServerList()
hostDNS, err = getDNSServerList() if err != nil {
if err != nil { err = fmt.Errorf("Could not get the host's DNS Server List. Error: %w", err)
err = fmt.Errorf("Could not get the host's DNS Server List. Error: %w", err) klog.ErrorS(err, "Encountered error while getting host's DNS Server List.")
klog.ErrorS(err, "Encountered error while getting host's DNS Server List.") return nil, err
return nil, err }
} hostSearch, err := getDNSSuffixList()
hostSearch, err = getDNSSuffixList() if err != nil {
if err != nil { err = fmt.Errorf("Could not get the host's DNS Suffix List. Error: %w", err)
err = fmt.Errorf("Could not get the host's DNS Suffix List. Error: %w", err) klog.ErrorS(err, "Encountered error while getting host's DNS Suffix List.")
klog.ErrorS(err, "Encountered error while getting host's DNS Suffix List.") return nil, err
return nil, err
}
} }
return &runtimeapi.DNSConfig{ return &runtimeapi.DNSConfig{
Servers: hostDNS, Servers: hostDNS,

View File

@ -20,8 +20,6 @@ limitations under the License.
package dns package dns
import ( import (
"testing"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
) )
@ -35,8 +33,3 @@ func fakeGetHostDNSConfigCustom(resolverConfig string) (*runtimeapi.DNSConfig, e
Searches: []string{testHostDomain}, Searches: []string{testHostDomain},
}, nil }, nil
} }
// getResolvConf returns the hostResolvConf string, which will be used to get the Host's DNS configuration.
func getResolvConf(t *testing.T) (string, func()) {
return hostResolvConf, func() {}
}