-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parse inspected console item definition (#212)
* parse output of /console/inspect command to populate resource fields * update README * generate mikrotik resource with pre-filled list of fields * query resource fields from remote system
- Loading branch information
1 parent
e3c0d79
commit 326ca07
Showing
11 changed files
with
477 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package consoleinspected | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// Parse parses definition of inspected console item and extracts items using splitStrategy. | ||
// | ||
// It returns console item struct with its subcommands, commands, arguments, etc. | ||
func Parse(input string, splitStrategy ItemsDefinitionSplitStrategy) (ConsoleItem, error) { | ||
chunks, err := splitStrategy.Split(input) | ||
if err != nil { | ||
return ConsoleItem{}, err | ||
} | ||
|
||
var result ConsoleItem | ||
result.Self = Item{} | ||
|
||
for _, v := range chunks { | ||
item, err := parseItem(v) | ||
if err != nil { | ||
return ConsoleItem{}, err | ||
} | ||
if item.Type == TypeSelf { | ||
result.Self = item | ||
continue | ||
} | ||
switch t := item.NodeType; t { | ||
case NodeTypeDir: | ||
result.Subcommands = append(result.Subcommands, item.Name) | ||
case NodeTypeArg: | ||
result.Arguments = append(result.Arguments, item) | ||
case NodeTypeCommand: | ||
result.Commands = append(result.Commands, item.Name) | ||
default: | ||
return ConsoleItem{}, fmt.Errorf("unknown node type %q", t) | ||
} | ||
} | ||
|
||
return result, nil | ||
} | ||
|
||
func parseItem(input string) (Item, error) { | ||
result := Item{} | ||
for _, v := range strings.Split(input, ";") { | ||
if strings.TrimSpace(v) == "" { | ||
continue | ||
} | ||
if strings.HasPrefix(v, "name=") { | ||
result.Name = strings.TrimPrefix(v, "name=") | ||
} | ||
if strings.HasPrefix(v, "node-type=") { | ||
result.NodeType = NodeType(strings.TrimPrefix(v, "node-type=")) | ||
} | ||
if strings.HasPrefix(v, "type=") { | ||
result.Type = Type(strings.TrimPrefix(v, "type=")) | ||
} | ||
} | ||
|
||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package consoleinspected | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestParse(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
input string | ||
expected ConsoleItem | ||
expectedError bool | ||
}{ | ||
{ | ||
name: "simple command", | ||
input: "name=add;node-type=cmd;type=self;name=comment;node-type=arg;type=child;name=copy-from;node-type=arg;type=child;", | ||
expected: ConsoleItem{ | ||
Self: Item{ | ||
Name: "add", | ||
NodeType: NodeTypeCommand, | ||
Type: TypeSelf, | ||
}, | ||
Arguments: []Item{ | ||
{Name: "comment", NodeType: NodeTypeArg, Type: TypeChild}, | ||
{Name: "copy-from", NodeType: NodeTypeArg, Type: TypeChild}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "command with subcommands", | ||
input: "name=list;node-type=dir;type=self;name=add;node-type=cmd;type=child;name=comment;node-type=cmd;type=child;name=edit;node-type=cmd;type=child;name=export;node-type=cmd;type=child;name=find;node-type=cmd;type=child;name=get;node-type=cmd;type=child;name=member;node-type=dir;type=child;name=print;node-type=cmd;type=child;name=remove;node-type=cmd;type=child;name=reset;node-type=cmd;type=child;name=set;node-type=cmd;type=child", | ||
expected: ConsoleItem{ | ||
Self: Item{ | ||
Name: "list", | ||
NodeType: NodeTypeDir, | ||
Type: TypeSelf, | ||
}, | ||
Commands: []string{ | ||
"add", | ||
"comment", | ||
"edit", | ||
"export", | ||
"find", | ||
"get", | ||
"print", | ||
"remove", | ||
"reset", | ||
"set", | ||
}, | ||
Subcommands: []string{"member"}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
item, err := Parse(tc.input, DefaultSplitStrategy) | ||
if !assert.Equal(t, !tc.expectedError, err == nil) || tc.expectedError { | ||
return | ||
} | ||
assert.Equal(t, tc.expected, item) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package consoleinspected | ||
|
||
import "strings" | ||
|
||
var DefaultSplitStrategy = splitStrategyFunc(orderedSplit) | ||
|
||
type splitStrategyFunc func(string) ([]string, error) | ||
|
||
func (f splitStrategyFunc) Split(in string) ([]string, error) { | ||
return f(in) | ||
} | ||
|
||
// orderedSplit splits items definition using order of fields. | ||
// | ||
// Each 'name=' key starts a new item definition. | ||
func orderedSplit(in string) ([]string, error) { | ||
result := []string{} | ||
|
||
buf := strings.Builder{} | ||
for _, v := range strings.Split(in, ";") { | ||
if strings.TrimSpace(v) == "" { | ||
continue | ||
} | ||
if strings.HasPrefix(v, "name=") { | ||
if buf.Len() > 0 { | ||
result = append(result, buf.String()) | ||
} | ||
buf.Reset() | ||
} | ||
buf.WriteString(v) | ||
buf.WriteString(";") | ||
} | ||
if buf.Len() > 0 { | ||
result = append(result, buf.String()) | ||
} | ||
|
||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package consoleinspected | ||
|
||
const ( | ||
// NodeTypeDir represents console menu level. | ||
NodeTypeDir NodeType = "dir" | ||
|
||
// NodeTypeCommand represents console command that can be called. | ||
NodeTypeCommand NodeType = "cmd" | ||
|
||
// NodeTypeArg represents console item that is argument to a command. | ||
NodeTypeArg NodeType = "arg" | ||
|
||
// TypeSelf is console item type for currently inspected item. | ||
TypeSelf Type = "self" | ||
|
||
// TypeChild is console item type of all items within inspected container. | ||
TypeChild Type = "child" | ||
) | ||
|
||
type ( | ||
// NodeType is dedicated type that holds values of "node-type" field of console item. | ||
NodeType string | ||
|
||
// Type is dedicated type that holds values of "type" field of console item. | ||
Type string | ||
|
||
// Item represents inspected console items. | ||
Item struct { | ||
NodeType NodeType `mikrotik:"node-type"` | ||
Type Type `mikrotik:"type"` | ||
Name string `mikrotik:"name"` | ||
} | ||
|
||
// ConsoleItem represents inspected console item with extracted commands, arguments, etc. | ||
ConsoleItem struct { | ||
// Self holds information about current console item. | ||
Self Item | ||
|
||
// Commands holds a list of commands available for this menu level. | ||
// Valid only for ConsoleItem of type NodeTypeDir. | ||
Commands []string | ||
|
||
// Subcommands holds a list of commands for the nested menu level. | ||
// Valid only for ConsoleItem of type NodeTypeDir. | ||
Subcommands []string | ||
|
||
// Arguments holds a list of argument items for a command. | ||
// Valid only for ConsoleItem of type NodeItemCommand. | ||
Arguments []Item | ||
} | ||
) | ||
|
||
type ( | ||
ItemsDefinitionSplitStrategy interface { | ||
// Split splits set of items definition represented by a single string into chunks of separate item definitions. | ||
Split(string) ([]string, error) | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package client | ||
|
||
import ( | ||
"strings" | ||
|
||
consoleinspected "github.com/ddelnano/terraform-provider-mikrotik/client/console-inspected" | ||
) | ||
|
||
func (c Mikrotik) InspectConsoleCommand(command string) (consoleinspected.ConsoleItem, error) { | ||
client, err := c.getMikrotikClient() | ||
if err != nil { | ||
return consoleinspected.ConsoleItem{}, err | ||
} | ||
normalizedCommand := strings.ReplaceAll(command[1:], "/", ",") | ||
cmd := []string{"/console/inspect", "as-value", "=path=" + normalizedCommand, "=request=child"} | ||
reply, err := client.RunArgs(cmd) | ||
if err != nil { | ||
return consoleinspected.ConsoleItem{}, err | ||
} | ||
var items []consoleinspected.Item | ||
var result consoleinspected.ConsoleItem | ||
if err := Unmarshal(*reply, &items); err != nil { | ||
return consoleinspected.ConsoleItem{}, err | ||
} | ||
|
||
for _, v := range items { | ||
if v.Type == consoleinspected.TypeSelf { | ||
result.Self = v | ||
continue | ||
} | ||
switch v.NodeType { | ||
case consoleinspected.NodeTypeArg: | ||
result.Arguments = append(result.Arguments, v) | ||
case consoleinspected.NodeTypeCommand: | ||
result.Commands = append(result.Commands, v.Name) | ||
case consoleinspected.NodeTypeDir: | ||
result.Subcommands = append(result.Subcommands, v.Name) | ||
} | ||
} | ||
|
||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.