253 lines
7.5 KiB
Go
253 lines
7.5 KiB
Go
package resolvconf
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const resolv1 = `nameserver 1.1.1.1
|
|
`
|
|
|
|
const resolv2 = `search example.com
|
|
nameserver 1.1.1.1
|
|
options edns0
|
|
`
|
|
|
|
func TestNew(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
baseContent string
|
|
nameservers []string
|
|
options []string
|
|
searches []string
|
|
ipv6 bool
|
|
hostns bool
|
|
keepHostServers bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "simple resolv.conf",
|
|
baseContent: resolv1,
|
|
want: resolv1,
|
|
},
|
|
{
|
|
name: "simple resolv.conf with search and options",
|
|
baseContent: resolv2,
|
|
want: resolv2,
|
|
},
|
|
{
|
|
name: "simple resolv.conf with comments",
|
|
baseContent: "#some comment\n" + resolv2,
|
|
want: resolv2,
|
|
},
|
|
{
|
|
name: "overwrite default nameservers",
|
|
baseContent: resolv2,
|
|
nameservers: []string{"1.2.3.4", "5.6.7.8"},
|
|
want: "search example.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\noptions edns0\n",
|
|
},
|
|
{
|
|
name: "overwrite default options",
|
|
baseContent: resolv2,
|
|
options: []string{"ndots:2"},
|
|
want: "search example.com\nnameserver 1.1.1.1\noptions ndots:2\n",
|
|
},
|
|
{
|
|
name: "overwrite default searches",
|
|
baseContent: resolv2,
|
|
searches: []string{"test.com"},
|
|
want: "search test.com\nnameserver 1.1.1.1\noptions edns0\n",
|
|
},
|
|
{
|
|
name: "dot in searches should unset all search domains",
|
|
baseContent: resolv2,
|
|
searches: []string{"."},
|
|
want: "nameserver 1.1.1.1\noptions edns0\n",
|
|
},
|
|
{
|
|
name: "dot in searches should unset all search domains even with keepHostServers",
|
|
baseContent: resolv2,
|
|
searches: []string{"."},
|
|
keepHostServers: true,
|
|
want: "nameserver 1.1.1.1\noptions edns0\n",
|
|
},
|
|
{
|
|
name: "overwrite all",
|
|
baseContent: resolv2,
|
|
nameservers: []string{"1.2.3.4", "5.6.7.8"},
|
|
options: []string{"ndots:2"},
|
|
searches: []string{"test.com"},
|
|
want: "search test.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\noptions ndots:2\n",
|
|
},
|
|
{
|
|
name: "overwrite all and unset search",
|
|
baseContent: resolv2,
|
|
nameservers: []string{"1.2.3.4", "5.6.7.8"},
|
|
options: []string{"ndots:2"},
|
|
searches: []string{"."},
|
|
want: "nameserver 1.2.3.4\nnameserver 5.6.7.8\noptions ndots:2\n",
|
|
},
|
|
{
|
|
name: "set all and keep host server",
|
|
baseContent: resolv2,
|
|
nameservers: []string{"1.2.3.4", "5.6.7.8"},
|
|
options: []string{"ndots:2"},
|
|
searches: []string{"test.com"},
|
|
keepHostServers: true,
|
|
want: "search test.com example.com\nnameserver 1.2.3.4\nnameserver 5.6.7.8\nnameserver 1.1.1.1\noptions ndots:2 edns0\n",
|
|
},
|
|
{
|
|
name: "localhost nameservers should be filtered and use defaults instead",
|
|
baseContent: "nameserver 127.0.0.1\nnameserver ::1\n",
|
|
want: "nameserver 8.8.8.8\nnameserver 8.8.4.4\n",
|
|
},
|
|
{
|
|
name: "localhost nameservers should not be filtered with hostns",
|
|
baseContent: "nameserver 127.0.0.1\nnameserver ::1\n",
|
|
hostns: true,
|
|
want: "nameserver 127.0.0.1\nnameserver ::1\n",
|
|
},
|
|
{
|
|
name: "ipv6 nameservers should be filtered when ipv6 is not set",
|
|
baseContent: "nameserver 1.1.1.1\nnameserver fd::1\n",
|
|
want: "nameserver 1.1.1.1\n",
|
|
},
|
|
{
|
|
name: "ipv6 nameservers should not be filtered when ipv6 is set",
|
|
baseContent: "nameserver 1.1.1.1\nnameserver fd::1\n",
|
|
ipv6: true,
|
|
want: "nameserver 1.1.1.1\nnameserver fd::1\n",
|
|
},
|
|
{
|
|
name: "ipv6 link local must always be filtered when netns is private",
|
|
baseContent: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
|
|
ipv6: true,
|
|
want: "nameserver 1.1.1.1\nnameserver fd::1\n",
|
|
},
|
|
{
|
|
name: "ipv6 link local must not be filtered when netns is host",
|
|
baseContent: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
|
|
hostns: true,
|
|
want: "nameserver 1.1.1.1\nnameserver fe80::1%eth1\nnameserver fd::1\n",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
base := filepath.Join(t.TempDir(), "resolv.conf")
|
|
target := filepath.Join(t.TempDir(), "new-resolv.conf")
|
|
err := os.WriteFile(base, []byte(tt.baseContent), 0o644)
|
|
assert.NoError(t, err, "write tmp resolv.conf")
|
|
var namespaces []specs.LinuxNamespace
|
|
if !tt.hostns {
|
|
namespaces = []specs.LinuxNamespace{
|
|
{Type: specs.NetworkNamespace},
|
|
}
|
|
}
|
|
err = New(&Params{
|
|
Path: target,
|
|
Nameservers: tt.nameservers,
|
|
Searches: tt.searches,
|
|
Options: tt.options,
|
|
IPv6Enabled: tt.ipv6,
|
|
KeepHostServers: tt.keepHostServers,
|
|
Namespaces: namespaces,
|
|
resolvConfPath: base,
|
|
})
|
|
assert.NoError(t, err, "New()")
|
|
content, err := os.ReadFile(target)
|
|
assert.NoError(t, err, "read tmp resolv.conf)")
|
|
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAdd(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
content string
|
|
nameservers []string
|
|
want string
|
|
}{
|
|
{
|
|
name: "add single nameserver",
|
|
content: resolv1,
|
|
nameservers: []string{"1.2.3.4"},
|
|
want: "nameserver 1.2.3.4\n" + resolv1,
|
|
},
|
|
{
|
|
name: "add single nameserver with search and options",
|
|
content: resolv2,
|
|
nameservers: []string{"1.2.3.4"},
|
|
want: `search example.com
|
|
nameserver 1.2.3.4
|
|
nameserver 1.1.1.1
|
|
options edns0
|
|
`,
|
|
},
|
|
{
|
|
name: "add three nameservers",
|
|
content: resolv1,
|
|
nameservers: []string{"1.2.3.4", "2.3.4.5", "3.4.5.6"},
|
|
want: "nameserver 1.2.3.4\nnameserver 2.3.4.5\nnameserver 3.4.5.6\n" + resolv1,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
resolvPath := filepath.Join(t.TempDir(), "resolv.conf")
|
|
err := os.WriteFile(resolvPath, []byte(tt.content), 0o644)
|
|
assert.NoError(t, err, "write tmp resolv.conf")
|
|
err = Add(resolvPath, tt.nameservers)
|
|
assert.NoError(t, err, "Add()")
|
|
content, err := os.ReadFile(resolvPath)
|
|
assert.NoError(t, err, "read tmp resolv.conf)")
|
|
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRemove(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
content string
|
|
nameservers []string
|
|
want string
|
|
}{
|
|
{
|
|
name: "remove single nameserver",
|
|
content: resolv1,
|
|
nameservers: []string{"1.1.1.1"},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "remove single nameserver with search and options",
|
|
content: resolv2,
|
|
nameservers: []string{"1.1.1.1"},
|
|
want: `search example.com
|
|
options edns0
|
|
`,
|
|
},
|
|
{
|
|
name: "remove three nameservers",
|
|
content: "nameserver 1.2.3.4\nnameserver 2.3.4.5\nnameserver 3.4.5.6\n" + resolv1,
|
|
nameservers: []string{"1.2.3.4", "2.3.4.5", "3.4.5.6"},
|
|
want: resolv1,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
resolvPath := filepath.Join(t.TempDir(), "resolv.conf")
|
|
err := os.WriteFile(resolvPath, []byte(tt.content), 0o644)
|
|
assert.NoError(t, err, "write tmp resolv.conf")
|
|
err = Remove(resolvPath, tt.nameservers)
|
|
assert.NoError(t, err, "Remove()")
|
|
content, err := os.ReadFile(resolvPath)
|
|
assert.NoError(t, err, "read tmp resolv.conf)")
|
|
assert.Equal(t, tt.want, string(content), "expected resolv.conf does not match")
|
|
})
|
|
}
|
|
}
|