Ejemplo n.º 1
0
func getHostname(root *command.ConfNode) string {
	node, err := root.Get("hostname")
	if err != nil {
		return "hostname?"
	}

	return command.LastToken(node.Children[0].Path)
}
Ejemplo n.º 2
0
func checkPassword(root *command.ConfNode, username, password string) bool {
	path := fmt.Sprintf("username %s password", username)

	node, err := root.Get(path)
	if err != nil {
		return false
	}

	if len(node.Children) != 1 {
		return false
	}

	return password == command.LastToken(node.Children[0].Path)
}
Ejemplo n.º 3
0
func TestConf(t *testing.T) {

	app := &testApp{
		cmdRoot:           &command.CmdNode{MinLevel: command.EXEC},
		confRootCandidate: &command.ConfNode{},
		confRootActive:    &command.ConfNode{},
	}

	hardware := fwd.NewDataplaneBogus()

	listInterfaces := func() ([]string, []string) {
		ifaces, vrfs, err := hardware.Interfaces()
		if err != nil {
			t.Errorf("hardware.Interfaces(): error: %v", err)
		}
		return ifaces, vrfs
	}
	listCommitId := func() []string {
		return []string{"BOGUS:TestConf:listCommitId"}
	}
	command.LoadKeywordTable(listInterfaces, listCommitId)

	root := app.cmdRoot
	cmdNone := command.CMD_NONE
	cmdConf := command.CMD_CONF

	cmdBogus := func(ctx command.ConfContext, node *command.CmdNode, line string, c command.CmdClient) {
	}

	command.CmdInstall(root, cmdConf, "interface {IFNAME} description {ANY}", command.CONF, command.HelperIfaceDescr, command.ApplyBogus, "Set interface description")
	command.CmdInstall(root, cmdConf, "interface {IFNAME} ipv4 address {IFADDR}", command.CONF, command.HelperIfaceAddr, command.ApplyBogus, "Assign IPv4 address to interface")
	command.CmdInstall(root, cmdConf, "interface {IFNAME} ipv6 address {IFADDR6}", command.CONF, cmdBogus, command.ApplyBogus, "Assign IPv6 address to interface")
	command.CmdInstall(root, cmdConf, "interface {IFNAME} shutdown", command.CONF, cmdBogus, command.ApplyBogus, "Disable interface")
	command.CmdInstall(root, cmdConf, "ip routing", command.CONF, cmdBogus, command.ApplyBogus, "Enable IP routing")
	command.CmdInstall(root, cmdConf, "hostname (HOSTNAME)", command.CONF, command.HelperHostname, command.ApplyBogus, "Assign hostname")
	command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item")

	c := &testClient{outputChannel: make(chan string)}
	close(c.outputChannel) // closed channel will break writers

	if err := command.Dispatch(app, "", c, command.CONF, false); err != nil {
		t.Errorf("empty command rejected: %v", err)
	}

	if err := command.Dispatch(app, "      ", c, command.CONF, false); err != nil {
		t.Errorf("blank command rejected: %v", err)
	}

	if err := command.Dispatch(app, "  !xxx    ", c, command.CONF, false); err != nil {
		t.Errorf("comment command ! rejected: %v", err)
	}

	if err := command.Dispatch(app, "  #xxx    ", c, command.CONF, false); err != nil {
		t.Errorf("comment command # rejected: %v", err)
	}

	if err := command.Dispatch(app, "xxxxxx", c, command.CONF, false); err == nil {
		t.Errorf("bad command accepted")
	}

	command.Dispatch(app, "hostname nexthop-router", c, command.CONF, false)
	if host := getHostname(app.ConfRootCandidate()); host != "nexthop-router" {
		t.Errorf("bad hostname: %s", host)
	}

	command.Dispatch(app, "int eth0 desc  aa  bb   ccc", c, command.CONF, false)
	node, err := app.confRootCandidate.Get("interface eth0 description")
	if err != nil || node == nil {
		t.Errorf("bad description: %v", err)
		return
	}
	if node.Path != "interface eth0 description" {
		t.Errorf("bad description path: [%s]", node.Path)
	}
	if len(node.Children) != 1 {
		t.Errorf("bad description value count: %d", len(node.Children))
	}
	if v := command.DescriptionDecode(command.LastToken(node.Children[0].Path)); v != " aa  bb   ccc" {
		t.Errorf("bad description value: [%s]", v)
	}

	command.Dispatch(app, "no int eth0 desc xxxxxxx", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth0 description")
	if node != nil || err == nil {
		t.Errorf("eth0 description should not be present: node=[%v] error=[%v]", node, err)
	}

	command.Dispatch(app, "int eth1 desc ddd   eee   fff ", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth1 description")
	if err != nil {
		t.Errorf("bad description: %v", err)
	}
	if node.Path != "interface eth1 description" {
		t.Errorf("bad description path: [%s]", node.Path)
	}
	if len(node.Children) != 1 {
		t.Errorf("bad description value count: %d", len(node.Children))
	}
	if v := command.DescriptionDecode(command.LastToken(node.Children[0].Path)); v != "ddd   eee   fff " {
		t.Errorf("bad description value: [%s]", v)
	}

	command.Dispatch(app, "no int eth1 desc", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth1 description")
	if node != nil || err == nil {
		t.Errorf("eth1 description should not be present: node=[%v] error=[%v]", node, err)
	}

	command.Dispatch(app, "int eth2 ipv4 addr 1.1.1.1/1", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth2 ipv4 address")
	if err != nil {
		t.Errorf("bad eth2 address 1: %v", err)
		return
	}
	if len(node.Children) != 1 {
		t.Errorf("wrong number of eth2 addresses (expected=1): %d", len(node.Children))
	}
	command.Dispatch(app, "int eth2 ipv4 addr 2.2.2.2/2", c, command.CONF, false)
	if err != nil {
		t.Errorf("bad eth2 address 2: %v", err)
		return
	}
	if len(node.Children) != 2 {
		t.Errorf("wrong number of eth2 addresses (expected=2): %d", len(node.Children))
	}
	command.Dispatch(app, "int eth2 ipv4 addr 3.3.3.3/3", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth2 ipv4 address")
	if err != nil {
		t.Errorf("bad eth2 address 3: %v", err)
		return
	}
	if len(node.Children) != 3 {
		t.Errorf("wrong number of eth2 addresses (expected=3): %d", len(node.Children))
	}
	command.Dispatch(app, "no int eth2 ipv4 addr 3.3.3.3/3", c, command.CONF, false)
	if len(node.Children) != 2 {
		t.Errorf("wrong number of eth2 addresses (expected=2): %d", len(node.Children))
	}
	command.Dispatch(app, "no int eth2 ipv4 addr", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth2 ipv4 address")
	if node != nil || err == nil {
		t.Errorf("eth2 should not have address: node=[%v] error=[%v]", node, err)
	}

	command.Dispatch(app, "int eth3 ipv4 addr 1.1.1.1/1", c, command.CONF, false)
	command.Dispatch(app, "int eth3 ipv4 addr 2.2.2.2/2", c, command.CONF, false)
	command.Dispatch(app, "int eth3 ipv4 addr 3.3.3.3/3", c, command.CONF, false)
	command.Dispatch(app, "int eth3 ipv4 addr 4.4.4.4/4", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth3 ipv4 address")
	if err != nil {
		t.Errorf("bad eth3 address: %v", err)
		return
	}
	if len(node.Children) != 4 {
		t.Errorf("wrong number of eth3 addresses (expected=4): %d", len(node.Children))
	}
	node, err = app.confRootCandidate.Get("interface eth3 ipv4")
	if err != nil {
		t.Errorf("eth3 should have ipv4: node=[%v] error=[%v]", node, err)
	}
	command.Dispatch(app, "no int eth3 ipv4", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth3")
	if node != nil || err == nil {
		t.Errorf("eth3 should not exist: node=[%v] error=[%v]", node, err)
	}

	command.Dispatch(app, "int eth4 ipv4 addr 1.1.1.1/1", c, command.CONF, false)
	command.Dispatch(app, "int eth4 desc abc", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth4 ipv4 address")
	if err != nil {
		t.Errorf("bad eth4 address: %v", err)
		return
	}
	if len(node.Children) != 1 {
		t.Errorf("wrong number of eth4 addresses (expected=1): %d", len(node.Children))
	}
	node, err = app.confRootCandidate.Get("interface eth4 description")
	if err != nil {
		t.Errorf("bad eth4 description: %v", err)
		return
	}
	command.Dispatch(app, "no int eth4 ipv4 addr", c, command.CONF, false)
	node, err = app.confRootCandidate.Get("interface eth4 ipv4")
	if node != nil || err == nil {
		t.Errorf("eth4 should not have ipv4: node=[%v] error=[%v]", node, err)
		return
	}
	node, err = app.confRootCandidate.Get("interface eth4")
	if node == nil || err != nil {
		t.Errorf("eth4 should exist: node=[%v] error=[%v]", node, err)
		return
	}

	f := func() {
		command.Dispatch(app, "interface eth5 ipv4 address 1.1.1.1/24", c, command.CONF, false)
	}
	noCmd, err := command.CmdFind(root, "no X", command.CONF, true)
	if err != nil {
		t.Errorf("could not find 'no' command: %v", err)
	}
	f()
	cmd := "no interface eth5 ipv4 address 1.1.1.1/24"
	if err := command.CmdNo(app, noCmd, cmd, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", cmd, err)
	}
	f()
	cmd = "no interface eth5 ipv4 address"
	if err := command.CmdNo(app, noCmd, cmd, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", cmd, err)
	}
	f()
	cmd = "no interface eth5 ipv4"
	if err := command.CmdNo(app, noCmd, cmd, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", cmd, err)
	}
	f()
	cmd = "no interface eth5"
	if err := command.CmdNo(app, noCmd, cmd, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", cmd, err)
	}
	f()
	cmd = "no interface"
	if err := command.CmdNo(app, noCmd, cmd, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", cmd, err)
	}
	f()
	cmd = "no"
	if err := command.CmdNo(app, noCmd, cmd, c); err == nil {
		t.Errorf("bad cmd silently accepted: [%s]", cmd)
	}

}
Ejemplo n.º 4
0
func TestConf(t *testing.T) {

	app := &ripTestApp{
		cmdRoot:           &command.CmdNode{MinLevel: command.EXEC},
		confRootCandidate: &command.ConfNode{},
		confRootActive:    &command.ConfNode{},
	}

	hardware := fwd.NewDataplaneBogus()

	listInterfaces := func() ([]string, []string) {
		ifaces, vrfs, err := hardware.Interfaces()
		if err != nil {
			t.Errorf("hardware.Interfaces(): error: %v", err)
		}
		return ifaces, vrfs
	}
	listCommitId := func() []string {
		return []string{"BOGUS:rip.TestConf:listCommitId"}
	}
	command.LoadKeywordTable(listInterfaces, listCommitId)

	root := app.cmdRoot
	cmdNone := command.CMD_NONE
	cmdConf := command.CMD_CONF

	command.CmdInstall(root, cmdConf, "router rip", command.CONF, cmdRip, applyRip, "Enable RIP protocol")
	command.CmdInstall(root, cmdConf, "router rip network {NETWORK}", command.CONF, cmdRipNetwork, applyRipNet, "Insert network into RIP protocol")
	command.CmdInstall(root, cmdNone, "no {ANY}", command.CONF, command.HelperNo, nil, "Remove a configuration item")

	c := NewRipTestClient(func(string) {})

	r := "router rip"
	net := fmt.Sprintf("%s network", r)
	n1 := "1.1.1.0/24"
	n2 := "2.2.2.0/24"
	net1 := fmt.Sprintf("%s %s", net, n1)
	net2 := fmt.Sprintf("%s %s", net, n2)
	command.Dispatch(app, net1, c, command.CONF, false)
	command.Dispatch(app, net2, c, command.CONF, false)

	{
		node, err := app.confRootCandidate.Get(net)
		if node == nil || err != nil {
			t.Errorf("missing config node=[%s] error: %v", net, err)
			return
		}
		if node.Path != net {
			t.Errorf("config node mismatch want=[%s] got=[%s]", net, node.Path)
		}
		if len(node.Children) != 2 {
			t.Errorf("bad number of values want=2 got=%d", len(node.Children))
		}
		if v := command.LastToken(node.Children[0].Path); v != n1 {
			t.Errorf("unexpected 1st network want=%s got=%s", n1, v)
		}
		if v := command.LastToken(node.Children[1].Path); v != n2 {
			t.Errorf("unexpected 2nd network want=%s got=%s", n2, v)
		}
	}

	nonet1 := fmt.Sprintf("no %s", net1)
	nonet2 := fmt.Sprintf("no %s", net2)

	/*
		noCmd, err := command.CmdFind(root, "no X", command.CONF, true)
		if err != nil {
			t.Errorf("could not find 'no' command: %v", err)
			return
		}
	*/

	dumpConf(app.confRootCandidate, "conf1:")

	fmt.Printf("trying: [%s]\n", nonet1)
	if err := command.CmdNo(app, nil, nonet1, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", nonet1, err)
		return
	}

	dumpConf(app.confRootCandidate, "conf2:")
	fmt.Printf("trying: [%s]\n", nonet2)
	if err := command.CmdNo(app, nil, nonet2, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", nonet2, err)
		return
	}

	dumpConf(app.confRootCandidate, "conf3:")

	{
		node, err := app.confRootCandidate.Get(net)
		if node != nil || err == nil {
			t.Errorf("unexpected config node=[%s] error: %v", net, err)
		}
	}

	{
		node, err := app.confRootCandidate.Get(r)
		if node == nil || err != nil {
			t.Errorf("missing config node=[%s] error: %v", r, err)
		}
	}

}