Added windows-specific hostfile format, and tests

master
Chris Bednarski 4 years ago
parent c4e4f6d820
commit aecfa8f689

@ -1,10 +1,13 @@
package hostess
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net"
"os"
"runtime"
"sort"
"strings"
)
@ -374,9 +377,9 @@ func (h *Hostlist) GetUniqueIPs() []net.IP {
// 2. Commented items are sorted displayed
// 3. 127.* appears at the top of the list (so boot resolvers don't break)
// 4. When present, "localhost" will always appear first in the domain list
func (h *Hostlist) Format() []byte {
func (h *Hostlist) FormatLinux() []byte {
h.Sort()
out := []byte{}
out := bytes.Buffer{}
// We want to output one line of hostnames per IP, so first we get that
// list of IPs and iterate.
@ -400,19 +403,49 @@ func (h *Hostlist) Format() []byte {
// Finally, if the bucket contains anything, concatenate it all
// together and append it to the output. Also add a newline.
if len(enabledIPs) > 0 {
concat := fmt.Sprintf("%s %s", IP.String(), strings.Join(enabledIPs, " "))
out = append(out, []byte(concat)...)
out = append(out, []byte("\n")...)
out.WriteString(fmt.Sprintf("%s %s\n", IP.String(), strings.Join(enabledIPs, " ")))
}
if len(disabledIPs) > 0 {
concat := fmt.Sprintf("# %s %s", IP.String(), strings.Join(disabledIPs, " "))
out = append(out, []byte(concat)...)
out = append(out, []byte("\n")...)
out.WriteString(fmt.Sprintf("# %s %s\n", IP.String(), strings.Join(disabledIPs, " ")))
}
}
return out
return out.Bytes()
}
func (h Hostlist) FormatWindows() []byte {
h.Sort()
out := bytes.Buffer{}
for _, hostname := range h {
out.WriteString(hostname.Format())
out.WriteString("\n")
}
return out.Bytes()
}
func (h *Hostlist) Format() []byte {
format := os.Getenv(EnvHostessFmt)
if format == "" {
format = runtime.GOOS
}
switch format {
case "windows":
return h.FormatWindows()
case "linux":
return h.FormatLinux()
default:
// Theoretically the Windows format might be more compatible but there
// are a lot of different operating systems, and they're almost all
// unix-based OSes, so we'll just assume the linux format is OK. For
// example, FreeBSD, MacOS, and Linux all use the same format and while
// I haven't checked OpenBSD or NetBSD, I am going to assume they are
// OK with this format. If not we can add a case above.
return h.FormatLinux()
}
}
// Dump exports all entries in the Hostlist as JSON

@ -3,7 +3,9 @@ package hostess_test
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"path/filepath"
"testing"
"github.com/cbednarski/hostess/hostess"
@ -95,6 +97,52 @@ func TestContainsDomainIp(t *testing.T) {
}
}
func TestFormatLinux(t *testing.T) {
hostfile := hostess.NewHostfile()
hostfile.Path = filepath.Join("testdata", "hostfile3")
if err := hostfile.Read(); err != nil {
t.Fatal(err)
}
if errs := hostfile.Parse(); len(errs) != 0 {
t.Fatal(errs)
}
expected, err := ioutil.ReadFile(filepath.Join("testdata", "expected-linux"))
if err != nil {
t.Fatal(err)
}
output := hostfile.Hosts.FormatLinux()
if !bytes.Equal(output, expected) {
t.Errorf("---- Expected ----\n%s\n---- Found----\n%s\n", expected, output)
}
}
func TestFormatWindows(t *testing.T) {
hostfile := hostess.NewHostfile()
hostfile.Path = filepath.Join("testdata", "hostfile3")
if err := hostfile.Read(); err != nil {
t.Fatal(err)
}
if errs := hostfile.Parse(); len(errs) != 0 {
t.Fatal(errs)
}
expected, err := ioutil.ReadFile(filepath.Join("testdata", "expected-windows"))
if err != nil {
t.Fatal(err)
}
output := hostfile.Hosts.FormatWindows()
if !bytes.Equal(output, expected) {
t.Errorf("---- Expected ----\n%s\n---- Found----\n%s\n", expected, output)
}
}
func TestFormat(t *testing.T) {
hosts := hostess.NewHostlist()
hosts.Add(hostess.MustHostname(domain, ip, false))

@ -0,0 +1,8 @@
127.0.0.1 localhost
127.0.1.1 robobrain
# 192.168.0.1 pie.dev.example.com
192.168.0.2 cookie.example.com
192.168.1.1 pie.example.com strawberry.pie.example.com
::1 localhost cake.example.com hostname.candy hostname.pie
fe:23b3:890e:342e::ef chocolate.pie.example.com strawberry.pie.example.com
# fe:23b3:890e:342e::ef chocolate.cake.example.com chocolate.cookie.example.com chocolate.ru.example.com chocolate.tr.example.com dev.strawberry.pie.example.com

@ -0,0 +1,17 @@
127.0.0.1 localhost
127.0.1.1 robobrain
# 192.168.0.1 pie.dev.example.com
192.168.0.2 cookie.example.com
192.168.1.1 pie.example.com
192.168.1.1 strawberry.pie.example.com
::1 localhost
::1 cake.example.com
::1 hostname.candy
::1 hostname.pie
# fe:23b3:890e:342e::ef chocolate.cake.example.com
# fe:23b3:890e:342e::ef chocolate.cookie.example.com
fe:23b3:890e:342e::ef chocolate.pie.example.com
# fe:23b3:890e:342e::ef chocolate.ru.example.com
# fe:23b3:890e:342e::ef chocolate.tr.example.com
# fe:23b3:890e:342e::ef dev.strawberry.pie.example.com
fe:23b3:890e:342e::ef strawberry.pie.example.com

@ -0,0 +1,12 @@
#192.168.0.1 pie.dev.example.com
192.168.0.2 cookie.example.com
::1 hostname.pie hostname.candy cake.example.com
fe:23b3:890e:342e::ef strawberry.pie.example.com
# fe:23b3:890e:342e::ef dev.strawberry.pie.example.com
127.0.1.1 robobrain
# fe:23b3:890e:342e::ef chocolate.cake.example.com chocolate.ru.example.com chocolate.tr.example.com chocolate.cookie.example.com
fe:23b3:890e:342e::ef chocolate.pie.example.com
::1 localhost
127.0.0.1 localhost
192.168.1.1 pie.example.com
192.168.1.1 strawberry.pie.example.com

@ -4,6 +4,7 @@ import (
"io"
"io/ioutil"
"os"
"runtime"
"strings"
"testing"
@ -65,6 +66,20 @@ ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
if runtime.GOOS == "windows" {
expected = `127.0.0.1 localhost
127.0.0.1 myapp.local
127.0.1.1 ubuntu
192.168.0.30 raspberrypi
::1 ip6-localhost
::1 ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
}
if output != expected {
t.Errorf("--- Expected ---\n%s\n--- Found ---\n%s\n", expected, output)
}
@ -102,6 +117,22 @@ ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
if runtime.GOOS == "windows" {
expected = `127.0.0.1 localhost
127.0.0.1 my.new.website
127.0.1.1 ubuntu
10.20.0.23 myapp.local
192.168.0.30 raspberrypi
192.168.0.82 mediaserver
::1 ip6-localhost
::1 ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
}
if output != expected {
t.Errorf("--- Expected ---\n%s\n--- Found ---\n%s\n", expected, output)
}
@ -133,6 +164,18 @@ ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
if runtime.GOOS== "windows" {
expected = `127.0.0.1 localhost
127.0.1.1 ubuntu
::1 ip6-localhost
::1 ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
}
if output != expected {
t.Errorf("--- Expected ---\n%s\n--- Found ---\n%s\n", expected, output)
}
@ -166,6 +209,20 @@ ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
if runtime.GOOS == "windows" {
expected = `127.0.0.1 localhost
# 127.0.0.1 myapp.local
127.0.1.1 ubuntu
# 192.168.0.30 raspberrypi
::1 ip6-localhost
::1 ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
`
}
if output != expected {
t.Errorf("--- Expected ---\n%s\n--- Found ---\n%s\n", expected, output)
}

Loading…
Cancel
Save