Added dump and apply commands to provide JSON I/O

pull/13/head
Chris Bednarski 9 years ago
parent 46ea48f8e1
commit 8eb33b712c

@ -1,9 +1,10 @@
package main
import (
"os"
"github.com/cbednarski/hostess"
"github.com/codegangsta/cli"
"os"
)
func getCommand() string {
@ -111,7 +112,7 @@ func main() {
},
{
Name: "apply",
Usage: "apply a JSON hosts dict to your hosts file",
Usage: "add hostnames from a JSON file to the hosts file",
Action: hostess.Apply,
Flags: app.Flags,
},

@ -3,9 +3,11 @@ package hostess
import (
"bytes"
"fmt"
"github.com/codegangsta/cli"
"io/ioutil"
"os"
"strings"
"github.com/codegangsta/cli"
)
// ErrCantWriteHostFile indicates that we are unable to write to the hosts file
@ -231,10 +233,32 @@ func Fix(c *cli.Context) {
// Dump command outputs hosts file contents as JSON
func Dump(c *cli.Context) {
hostsfile := AlwaysLoadHostFile(c)
output, err := hostsfile.Hosts.Dump()
if err != nil {
MaybeError(c, err.Error())
}
fmt.Println(fmt.Sprintf("%s", output))
}
// Apply command adds hostnames to the hosts file from JSON
func Apply(c *cli.Context) {
if len(c.Args()) != 1 {
MaybeError(c, "Usage should be apply [filename]")
}
filename := c.Args()[0]
data, err := ioutil.ReadFile(filename)
if err != nil {
MaybeError(c, fmt.Sprintf("Unable to read %s: %s", filename, err))
}
hostfile := AlwaysLoadHostFile(c)
err = hostfile.Hosts.Apply(data)
if err != nil {
MaybeError(c, fmt.Sprintf("Error applying changes to hosts file: %s", err))
}
MaybeSaveHostFile(c, hostfile)
MaybePrintln(c, fmt.Sprintf("%s applied", filename))
}

@ -1,6 +1,7 @@
package hostess
import (
"encoding/json"
"errors"
"fmt"
"net"
@ -411,3 +412,23 @@ func (h *Hostlist) Format() []byte {
return out
}
// Dump exports all entries in the Hostlist as JSON
func (h *Hostlist) Dump() ([]byte, error) {
return json.MarshalIndent(h, "", " ")
}
// Apply imports all entries from the JSON input to this Hostlist
func (h *Hostlist) Apply(data []byte) error {
var hostnames Hostlist
err := json.Unmarshal(data, &hostnames)
if err != nil {
return err
}
for _, hostname := range hostnames {
h.Add(hostname)
}
return nil
}

@ -1,10 +1,12 @@
package hostess_test
import (
"bytes"
"fmt"
"github.com/cbednarski/hostess"
"net"
"testing"
"github.com/cbednarski/hostess"
)
func TestAddDuplicate(t *testing.T) {
@ -197,3 +199,50 @@ func ExampleHostlist_1() {
// # 127.0.0.1 google.com
// ::1 google.com
}
const hostsjson = `[
{
"domain": "google.com",
"ip": "127.0.0.1",
"enabled": false
},
{
"domain": "google.com",
"ip": "::1",
"enabled": true
}
]`
func TestDump(t *testing.T) {
hosts := hostess.NewHostlist()
hosts.Add(hostess.NewHostname("google.com", "127.0.0.1", false))
hosts.Add(hostess.NewHostname("google.com", "::1", true))
expected := []byte(hostsjson)
actual, _ := hosts.Dump()
if !bytes.Equal(actual, expected) {
t.Errorf("JSON output did not match expected output: %s", Diff(string(expected), string(actual)))
}
}
func TestApply(t *testing.T) {
hosts := hostess.NewHostlist()
hosts.Apply([]byte(hostsjson))
hostnameA := hostess.NewHostname("google.com", "127.0.0.1", false)
if !hosts.Contains(hostnameA) {
t.Errorf("Expected to find %s", hostnameA.Format())
}
hostnameB := hostess.NewHostname("google.com", "::1", true)
if !hosts.Contains(hostnameB) {
t.Errorf("Expected to find %s", hostnameB.Format())
}
hosts.Apply([]byte(hostsjson))
if hosts.Len() != 2 {
t.Error("Hostslist contains the wrong number of items, expected 2")
}
}

@ -33,10 +33,10 @@ func LooksLikeIPv6(ip string) bool {
// can cause unexpected behavior. Instead, use Hostlist's Add, Remove, Enable,
// and Disable methods.
type Hostname struct {
Domain string
IP net.IP
Enabled bool
IPv6 bool
Domain string `json:"domain"`
IP net.IP `json:"ip"`
Enabled bool `json:"enabled"`
IPv6 bool `json:"-"`
}
// NewHostname creates a new Hostname struct and automatically sets the IPv6

Loading…
Cancel
Save