-
Notifications
You must be signed in to change notification settings - Fork 245
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Query hosts dns servers and populate nodes config with it (#1650)
* query hosts dns servers and populate nodes config with it * fix * fix defer close * tests, func rename, etc * tests via cmp.Diff() * optimize dns ip match func * added docs --------- Co-authored-by: Roman Dodin <dodin.roman@gmail.com>
- Loading branch information
Showing
5 changed files
with
290 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package utils | ||
|
||
import ( | ||
"bufio" | ||
"io/fs" | ||
"net" | ||
"strings" | ||
|
||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// ExtractDNSServersFromResolvConf extracts IP addresses | ||
// of the DNS servers from the resolv.conf-formatted files passed in filenames list. | ||
// Returns a list of IP addresses of the DNS servers. | ||
func ExtractDNSServersFromResolvConf(filesys fs.FS, filenames []string) ([]string, error) { | ||
DNSServersMap := map[string]struct{}{} | ||
|
||
for _, filename := range filenames { | ||
readFile, err := filesys.Open(filename) | ||
if err != nil { | ||
log.Debugf("Error opening host DNS config %s: %v", filename, err) | ||
continue | ||
} | ||
|
||
fileScanner := bufio.NewScanner(readFile) | ||
fileScanner.Split(bufio.ScanLines) | ||
|
||
// check line by line for a match | ||
for fileScanner.Scan() { | ||
line := strings.TrimSpace(fileScanner.Text()) | ||
if strings.HasPrefix(line, "nameserver") { | ||
fields := strings.Fields(line) | ||
if len(fields) != 2 { | ||
continue | ||
} | ||
|
||
ip := net.ParseIP(fields[1]) | ||
if ip == nil || ip.IsLoopback() { | ||
continue | ||
} | ||
|
||
DNSServersMap[ip.String()] = struct{}{} | ||
} | ||
} | ||
|
||
readFile.Close() | ||
} | ||
|
||
if len(DNSServersMap) == 0 { | ||
return nil, nil | ||
} | ||
|
||
DNSServers := make([]string, 0, len(DNSServersMap)) | ||
for k := range DNSServersMap { | ||
DNSServers = append(DNSServers, k) | ||
} | ||
return DNSServers, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package utils | ||
|
||
import ( | ||
"io/fs" | ||
"strings" | ||
"testing" | ||
"testing/fstest" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/google/go-cmp/cmp/cmpopts" | ||
) | ||
|
||
func TestExtractDNSServersFromResolvConf(t *testing.T) { | ||
type args struct { | ||
filesys fs.FS | ||
filenames []string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want []string | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "One file local dns empty result", | ||
args: args{ | ||
filesys: fstest.MapFS{ | ||
"etc/resolv.conf": &fstest.MapFile{ | ||
Data: []byte( | ||
` | ||
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8). | ||
# Do not edit. | ||
# | ||
# This file might be symlinked as /etc/resolv.conf. If you're looking at | ||
# /etc/resolv.conf and seeing this text, you have followed the symlink. | ||
nameserver 127.0.0.53 | ||
options edns0 trust-ad | ||
search . | ||
`, | ||
), | ||
}, | ||
}, | ||
filenames: []string{"etc/resolv.conf"}, | ||
}, | ||
want: nil, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Two files local dns and two remote, two results", | ||
args: args{ | ||
filesys: fstest.MapFS{ | ||
"etc/resolv.conf": &fstest.MapFile{ | ||
Data: []byte( | ||
` | ||
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8). | ||
# Do not edit. | ||
# | ||
# This file might be symlinked as /etc/resolv.conf. If you're looking at | ||
# /etc/resolv.conf and seeing this text, you have followed the symlink. | ||
nameserver 1.1.1.1 | ||
options edns0 trust-ad | ||
search . | ||
`, | ||
), | ||
}, | ||
"etc/someother/resolv.conf": &fstest.MapFile{ | ||
Data: []byte( | ||
` | ||
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8). | ||
# Do not edit. | ||
nameserver 127.0.0.53 | ||
nameserver 8.8.8.8 | ||
options edns0 trust-ad | ||
search . | ||
`, | ||
), | ||
}, | ||
}, | ||
filenames: []string{"etc/resolv.conf", "etc/someother/resolv.conf"}, | ||
}, | ||
want: []string{"1.1.1.1", "8.8.8.8"}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Duplicat 8.8.8.8", | ||
args: args{ | ||
filesys: fstest.MapFS{ | ||
"etc/resolv.conf": &fstest.MapFile{ | ||
Data: []byte( | ||
` | ||
# Do not edit. | ||
nameserver 1.1.1.1 | ||
nameserver 8.8.8.8 | ||
options edns0 trust-ad | ||
search . | ||
`, | ||
), | ||
}, | ||
"etc/someother/resolv.conf": &fstest.MapFile{ | ||
Data: []byte( | ||
` | ||
nameserver 8.8.8.8 | ||
options edns0 trust-ad | ||
search . | ||
`, | ||
), | ||
}, | ||
}, | ||
filenames: []string{"etc/resolv.conf", "etc/someother/resolv.conf"}, | ||
}, | ||
want: []string{"1.1.1.1", "8.8.8.8"}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Files do not exist", | ||
args: args{ | ||
filesys: fstest.MapFS{}, | ||
filenames: []string{"etc/resolv.conf", "etc/someother/resolv.conf"}, | ||
}, | ||
want: nil, | ||
wantErr: false, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got, err := ExtractDNSServersFromResolvConf(tt.args.filesys, tt.args.filenames) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("ExtractDNSServerFromResolvConf() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if diff := cmp.Diff(tt.want, got, cmpopts.SortSlices(func(s1, s2 string) bool { | ||
switch strings.Compare(s1, s2) { | ||
case -1: | ||
return false | ||
case 0: | ||
return true | ||
} | ||
return true | ||
}, | ||
)); diff != "" { | ||
t.Errorf(diff) | ||
} | ||
}) | ||
} | ||
} |