Beispiel #1
0
func Example_diff2() {

	app, c := setup_diff()

	f := func(s string) {
		if err := command.Dispatch(app, s, c, command.CONF, false); err != nil {
			log.Printf("dispatch: [%s]: %v", s, err)
		}
	}

	f("hostname bgp1")
	f("hostname bgp2")
	f("router bgp 1 neighbor 1.1.1.1 remote-as 1")
	f("router bgp 1 neighbor 2.2.2.2 remote-as 1")
	f("router bgp 1 neighbor 3.3.3.3 remote-as 2")
	f("router bgp 2 neighbor 3.3.3.3 remote-as 2")
	f("router bgp 2 neighbor 4.4.4.4 remote-as 2")
	f("router bgp 2 neighbor 4.4.4.4 remote-as 3")

	if err := command.Dispatch(app, "commit", c, command.CONF, false); err != nil {
		log.Printf("dispatch: [commit]: %v", err)
	}

	nonet := "no router bgp 1"
	if err := command.CmdNo(app, nil, nonet, c); err != nil {
		log.Printf("cmd failed: [%s] error=[%v]", nonet, err)
		return
	}

	command.WriteConfig(app.confRootCandidate, &outputWriter{})
	// Output:
	// hostname bgp2
	// router bgp 2 neighbor 3.3.3.3 remote-as 2
	// router bgp 2 neighbor 4.4.4.4 remote-as 3
}
Beispiel #2
0
func Example_diff2() {

	app, c := setup_diff()

	f := func(s string) {
		if err := command.Dispatch(app, s, c, command.CONF, false); err != nil {
			log.Printf("dispatch: [%s]: %v", s, err)
		}
	}

	f("hostname rip1")
	f("hostname rip2")
	f("router rip network 1.1.1.0/24")
	f("router rip network 1.1.2.0/24")
	f("router rip network 1.1.3.0/24 cost 2")
	f("router rip network 1.1.4.0/24 cost 15")
	f("router rip vrf X network 1.1.1.0/24")
	f("router rip vrf X network 1.1.2.0/24")
	f("router rip vrf X network 1.1.3.0/24 cost 3")
	f("router rip vrf X network 1.1.3.0/24 cost 4")
	f("router rip vrf x network 1.1.1.1/32")
	f("username guest1 password secret1")
	f("username guest1 password secret2")
	f("username guest2 password secret3")

	if err := command.Dispatch(app, "commit", c, command.CONF, false); err != nil {
		log.Printf("dispatch: [commit]: %v", err)
	}

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

	nonet := "no router rip network"
	if err := command.CmdNo(app, nil, nonet, c); err != nil {
		log.Printf("cmd failed: [%s] error=[%v]", nonet, err)
		return
	}

	command.WriteConfig(app.confRootCandidate, &outputWriter{})
	// Output:
	// hostname rip2
	// router rip vrf X network 1.1.1.0/24
	// router rip vrf X network 1.1.2.0/24
	// router rip vrf X network 1.1.3.0/24 cost 4
	// router rip vrf x network 1.1.1.1/32
	// username guest1 password secret2
	// username guest2 password secret3
}
Beispiel #3
0
func Example_diff1() {

	app, c := setup_diff()

	f := func(s string) {
		if err := command.Dispatch(app, s, c, command.CONF, false); err != nil {
			log.Printf("dispatch: [%s]: %v", s, err)
		}
	}

	f("hostname bgp1")
	f("hostname bgp2")
	f("router bgp 1 neighbor 1.1.1.1 description  A  BB   C")
	f("router bgp 1 neighbor 1.1.1.1 description  AA  BB   C")
	f("router bgp 1 neighbor 1.1.1.1 remote-as 1")
	f("router bgp 1 neighbor 2.2.2.2 remote-as 1")
	f("router bgp 1 neighbor 3.3.3.3 remote-as 2")
	f("router bgp 2 neighbor 3.3.3.3 remote-as 2")
	f("router bgp 2 neighbor 4.4.4.4 remote-as 2")
	f("router bgp 2 neighbor 4.4.4.4 remote-as 3")

	command.WriteConfig(app.confRootCandidate, &outputWriter{})
	// Output:
	// hostname bgp2
	// router bgp 1 neighbor 1.1.1.1 description  AA  BB   C
	// router bgp 1 neighbor 1.1.1.1 remote-as 1
	// router bgp 1 neighbor 2.2.2.2 remote-as 1
	// router bgp 1 neighbor 3.3.3.3 remote-as 2
	// router bgp 2 neighbor 3.3.3.3 remote-as 2
	// router bgp 2 neighbor 4.4.4.4 remote-as 3
}
Beispiel #4
0
func Example_diff1() {

	app, c := setup_diff()

	f := func(s string) {
		if err := command.Dispatch(app, s, c, command.CONF, false); err != nil {
			log.Printf("dispatch: [%s]: %v", s, err)
		}
	}

	f("hostname rip1")
	f("hostname rip2")
	f("router rip network 1.1.1.0/24")
	f("router rip network 1.1.2.0/24")
	f("router rip network 1.1.3.0/24 cost 2")
	f("router rip network 1.1.4.0/24 cost 15")
	f("router rip vrf X network 1.1.1.0/24")
	f("router rip vrf X network 1.1.2.0/24")
	f("router rip vrf X network 1.1.3.0/24 cost 3")
	f("router rip vrf X network 1.1.3.0/24 cost 4")
	f("router rip vrf x network 1.1.1.1/32")
	f("username guest1 password secret1")
	f("username guest1 password secret2")
	f("username guest2 password secret3")

	command.WriteConfig(app.confRootCandidate, &outputWriter{})
	// Output:
	// hostname rip2
	// router rip network 1.1.1.0/24
	// router rip network 1.1.2.0/24
	// router rip network 1.1.3.0/24 cost 2
	// router rip network 1.1.4.0/24 cost 15
	// router rip vrf X network 1.1.1.0/24
	// router rip vrf X network 1.1.2.0/24
	// router rip vrf X network 1.1.3.0/24 cost 4
	// router rip vrf x network 1.1.1.1/32
	// username guest1 password secret2
	// username guest2 password secret3
}
Beispiel #5
0
func executeLine(ctx command.ConfContext, line string, history bool, c *Client) {
	log.Printf("executeLine: [%v]", line)

	status := c.Status()

	switch status {
	case command.MOTD:
		c.Sendln("")
		c.Sendln("vty server ready")
		c.Sendln("")
		if isAnyUserDefined(ctx.ConfRootActive()) {
			c.StatusSet(command.USER) // request user/password auth
		} else {
			c.StatusSet(command.EXEC) // login without user/password auth
		}
	case command.USER:
		c.EchoDisable()
		c.StatusSet(command.PASS)
		c.UsernameSet(line)
	case command.PASS:
		c.EchoEnable()
		if checkPassword(ctx.ConfRootActive(), c.Username(), line) {
			c.StatusSet(command.EXEC) // login allowed
		} else {
			c.StatusSet(command.USER) // request user again
		}
	case command.EXEC, command.ENAB, command.CONF:
		if err := command.Dispatch(ctx, line, c, status, history); err != nil {
			c.Sendln(fmt.Sprintf("executeLine: error: %v", err))
		}
	default:
		msg := fmt.Sprintf("unknown state for command: [%s]", line)
		log.Print(msg)
		c.Sendln(msg)
	}

	commandFeedback(c, getHostname(ctx.ConfRootActive()))
}
Beispiel #6
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)
	}

}
Beispiel #7
0
func TestPrune(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:TestPrune: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) {
		}
	*/

	cmdSimpleSet := func(ctx command.ConfContext, node *command.CmdNode, line string, c command.CmdClient) {
		ctx.ConfRootCandidate().Set(node.Path, line)
	}

	path := "a b c d e f g h i j"
	jPath := "b c d e f g h i j"
	hPath := "b c d e f g h"
	gPath := "b c d e f g"
	fPath := "b c d e f"

	command.CmdInstall(root, cmdConf, path, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune A")
	command.CmdInstall(root, cmdConf, fPath, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune F")
	command.CmdInstall(root, cmdConf, jPath, command.CONF, cmdSimpleSet, command.ApplyBogus, "Teste prune J")
	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

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

	command.Dispatch(app, path, c, command.CONF, false)

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

	noPath := fmt.Sprintf("no %s", path)
	if err := command.CmdNo(app, noCmd, noPath, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", noPath, err)
		return
	}

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

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

	command.Dispatch(app, jPath, c, command.CONF, false)

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

	noH := fmt.Sprintf("no %s", hPath)
	if err := command.CmdNo(app, noCmd, noH, c); err != nil {
		t.Errorf("cmd failed: [%s] error=[%v]", noH, err)
		return
	}

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

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

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

}
Beispiel #8
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)
		}
	}

}