Skip to content

Commit

Permalink
Merge pull request #112 from ohai89/feat/support-cumulus-linux-vtysh
Browse files Browse the repository at this point in the history
Add support for cumulus linux & vtysh
  • Loading branch information
carlmontanari authored Dec 8, 2022
2 parents 94eb57a + 9b4d241 commit 583fc0f
Show file tree
Hide file tree
Showing 17 changed files with 219 additions and 0 deletions.
66 changes: 66 additions & 0 deletions assets/platforms/cumulus_linux.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
platform-type: 'cumulus_linux'
default:
driver-type: "network"
privilege-levels:
exec:
name: "exec"
pattern: '(?im)^\S+@\S+:\S+:\S+\$\s*$'
previous-priv:
deescalate:
escalate:
escalate-auth: false
escalate-prompt:
configuration:
name: "configuration"
pattern: '(?im)^\S+@\S+:\S+:\S+#\s*$'
previous-priv: "exec"
deescalate: "exit"
escalate: "sudo su"
escalate-auth: true
escalate-prompt: ": "
default-desired-privilege-level: "exec"
failed-when-contains:
- "Permission denied"
- "ERROR:"
- "command not found"
textfsm-platform: ""
network-on-open:
- operation: "acquire-priv"
network-on-close:
- operation: "acquire-priv"
- operation: "channel.write"
input: "exit"
- operation: "channel.return"
variants:
root_login:
driver-type: "network"
privilege-levels:
exec:
name: "exec"
pattern: '(?im)^\S+@\S+:\S+:\S+#\s*$'
previous-priv:
deescalate:
escalate:
escalate-auth: false
escalate-prompt: ": "
configuration:
name: "configuration"
pattern: '(?im)^\S+@\S+:\S+:\S+#\s*$'
previous-priv: exec
deescalate:
escalate:
escalate-auth: false
escalate-prompt:
default-desired-privilege-level: "exec"
failed-when-contains:
- "Permission denied"
- "ERROR:"
textfsm-platform: ""
network-on-open:
- operation: "acquire-priv"
network-on-close:
- operation: "acquire-priv"
- operation: "channel.write"
input: "exit"
- operation: "channel.return"
43 changes: 43 additions & 0 deletions assets/platforms/cumulus_vtysh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
platform-type: 'cumulus_vtysh'
default:
driver-type: "network"
privilege-levels:
linux:
name: "linux"
pattern: '(?im)^\S+@\S+:\S+:\S+[\$|#]\s*$'
previous-priv:
deescalate:
escalate:
escalate-auth: false
escalate-prompt:
exec:
name: "exec"
pattern: '(?im)^[\w\.\-]+#\s*$'
previous-priv: "linux"
deescalate: "exit"
escalate: "vtysh"
escalate-auth: false
escalate-prompt:
configuration:
name: "configuration"
pattern: '(?im)^[\w\.\-]+\(config\)#\s*$'
previous-priv: "exec"
deescalate: "exit"
escalate: "configure terminal"
escalate-auth: false
escalate-prompt:
default-desired-privilege-level: "exec"
failed-when-contains:
- "Permission denied"
- "ERROR:"
- "% Unknown command"
- "% Command incomplete"
textfsm-platform: ""
network-on-open:
- operation: "acquire-priv"
network-on-close:
- operation: "acquire-priv"
- operation: "channel.write"
input: "exit"
- operation: "channel.return"
6 changes: 6 additions & 0 deletions driver/generic/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func prepareDriver(
options.WithFileTransportFile(resolveFile(t, payloadFile)),
options.WithTransportReadSize(1),
options.WithReadDelay(0),
options.WithFailedWhenContains([]string{
"% Ambiguous command",
"% Incomplete command",
"% Invalid input detected",
"% Unknown command",
}),
)
if err != nil {
t.Errorf("%s: encountered error creating generic Driver, error: %s", testName, err)
Expand Down
38 changes: 38 additions & 0 deletions driver/generic/sendcommand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,41 @@ func TestSendCommand(t *testing.T) {
t.Run(testName, f)
}
}

func testSendCommandFails(testName string, testCase *sendCommandTestCase) func(t *testing.T) {
return func(t *testing.T) {
t.Logf("%s: starting", testName)

d, _ := prepareDriver(t, testName, testCase.payloadFile)

r, err := d.SendCommand(testCase.command)
if err != nil {
t.Fatalf("%s: response object indicates failure",
testName)
}

if r.Failed == nil {
t.Fatalf(
"%s: expected r.Failed to be set",
testName,
)
}
}
}

func TestSendCommandFails(t *testing.T) {
cases := map[string]*sendCommandTestCase{
"send-command-failure-simple": {
description: "simple send command failure test",
command: "thiscommandshouldfail",
payloadFile: "send-command-failure-simple.txt",
stripPrompt: false,
eager: false,
},
}

for testName, testCase := range cases {
f := testSendCommandFails(testName, testCase)
t.Run(testName, f)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
thiscommandshouldfail

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
% Unknown command or computer name, or unable to find computer address
3 changes: 3 additions & 0 deletions driver/generic/test-fixtures/send-command-failure-simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
C3560CX#thiscommandshouldfail
% Unknown command or computer name, or unable to find computer address
C3560CX#
5 changes: 5 additions & 0 deletions examples/generic_driver/basics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func main() {

// note that there is a convenience wrapper around send interactive in the generic driver as
// well, so you could simply do `d.SendInteractive` here rather than poking the channel directly
// remember to refer to `.Result` object in that case
interactiveOutput, err := d.Channel.SendInteractive(events)
if err != nil {
fmt.Printf("failed to send interactive input to device; error: %+v\n", err)
Expand All @@ -84,6 +85,10 @@ func main() {
fmt.Printf("failed to send command; error: %+v\n", err)
return
}
if r.Failed != nil {
fmt.Printf("response objects indicates failure: %+v\n", r.Failed)
return
}

fmt.Printf(
"sent command '%s', output received (SendCommand):\n %s\n\n\n",
Expand Down
5 changes: 5 additions & 0 deletions examples/generic_driver/custom_logging/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("got some output: %s\n\n\n", r.Result)
}
5 changes: 5 additions & 0 deletions examples/generic_driver/default_logging/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("got some output: %s\n\n\n", r.Result)
}
5 changes: 5 additions & 0 deletions examples/generic_driver/interactive_prompts/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("interact response:\n%s\n", r.Result)
}
5 changes: 5 additions & 0 deletions examples/generic_driver/textfsm_integration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

parsedOut, err := r.TextFsmParse(*arg)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions examples/netconf_driver/basics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("Config result: %s", r.Result)
}
10 changes: 10 additions & 0 deletions examples/network_driver/basics/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ func main() {

return
}
if interactiveOutput.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", interactiveOutput.Failed)

return
}

fmt.Printf("output received (SendInteractive):\n %s\n\n\n", interactiveOutput.Result)

Expand All @@ -116,6 +121,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf(
"sent command '%s', output received (SendCommand):\n %s\n\n\n",
Expand Down
10 changes: 10 additions & 0 deletions examples/network_driver/platforms/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ func main() {
if err != nil {
fmt.Printf("failed to send interactive input to device; error: %+v\n", err)
}
if interactiveOutput.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", interactiveOutput.Failed)

return
}

fmt.Printf("output received (SendInteractive):\n %s\n\n\n", interactiveOutput.Result)

Expand All @@ -94,6 +99,11 @@ func main() {
fmt.Printf("failed to send command; error: %+v\n", err)
return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf(
"sent command '%s', output received (SendCommand):\n %s\n\n\n",
Expand Down
5 changes: 5 additions & 0 deletions examples/network_driver/privilege_levels/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("got running config: %s\n\n\n", r.Result)
}
5 changes: 5 additions & 0 deletions examples/network_driver/sending_configs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ func main() {

return
}
if r.Failed != nil {
fmt.Printf("response object indicates failure: %+v\n", r.Failed)

return
}

fmt.Printf("sending configs took %f seconds", r.ElapsedTime)
}

0 comments on commit 583fc0f

Please sign in to comment.