Skip to content
This repository has been archived by the owner on Oct 28, 2022. It is now read-only.

Commit

Permalink
Merge pull request #384 from karimra/gen-path-state-config
Browse files Browse the repository at this point in the history
add flags to control what kind of paths are generated
  • Loading branch information
karimra authored May 9, 2021
2 parents ba5159d + 13250f9 commit 437d8ce
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 25 deletions.
22 changes: 16 additions & 6 deletions app/generatePath.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"errors"
"fmt"

"github.com/spf13/cobra"
Expand All @@ -9,8 +10,11 @@ import (

func (a *App) GeneratePathPreRunE(cmd *cobra.Command, args []string) error {
a.Config.SetLocalFlagsFromFile(cmd)
if a.Config.GeneratePathSearch && a.Config.GeneratePathWithDescr {
return errors.New("flags --search and --descr cannot be used together")
}
if a.Config.LocalFlags.GeneratePathPathType != "xpath" && a.Config.LocalFlags.GeneratePathPathType != "gnmi" {
return fmt.Errorf("path-type must be one of 'xpath' or 'gnmi'")
return errors.New("path-type must be one of 'xpath' or 'gnmi'")
}
return nil
}
Expand All @@ -20,11 +24,15 @@ func (a *App) GeneratePathRunE(cmd *cobra.Command, args []string) error {
a.Config.GlobalFlags.Dir,
a.Config.GlobalFlags.File,
a.Config.GlobalFlags.Exclude,
a.Config.GeneratePathSearch,
a.Config.GeneratePathWithDescr,
a.Config.GeneratePathWithPrefix,
a.Config.GeneratePathWithTypes,
a.Config.GeneratePathPathType,
pathGenOpts{
search: a.Config.LocalFlags.GeneratePathSearch,
withDescr: a.Config.LocalFlags.GeneratePathWithDescr,
withTypes: a.Config.LocalFlags.GeneratePathWithPrefix,
withPrefix: a.Config.LocalFlags.GeneratePathWithTypes,
pathType: a.Config.LocalFlags.GeneratePathPathType,
stateOnly: a.Config.LocalFlags.GeneratePathState,
configOnly: a.Config.LocalFlags.GeneratePathConfig,
},
)
}

Expand All @@ -35,6 +43,8 @@ func (a *App) InitGeneratePathFlags(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&a.Config.LocalFlags.GeneratePathWithPrefix, "with-prefix", "", false, "include module/submodule prefix in path elements")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.GeneratePathWithTypes, "types", "", false, "print leaf type")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.GeneratePathSearch, "search", "", false, "search through path list")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.GeneratePathState, "state-only", "", false, "generate paths only for YANG leafs representing state data")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.GeneratePathConfig, "config-only", "", false, "generate paths only for YANG leafs representing config data")
cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) {
a.Config.FileConfig.BindPFlag(fmt.Sprintf("%s-%s", cmd.Name(), flag.Name), flag)
})
Expand Down
68 changes: 61 additions & 7 deletions app/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app

import (
"context"
"errors"
"fmt"
"os"
"strings"
Expand All @@ -13,7 +14,17 @@ import (
"github.com/spf13/pflag"
)

func (a *App) PathCmdRun(d, f, e []string, search, withDescr, withPrefix, withTypes bool, pType string) error {
type pathGenOpts struct {
search bool
withDescr bool
withTypes bool
withPrefix bool
pathType string
stateOnly bool
configOnly bool
}

func (a *App) PathCmdRun(d, f, e []string, pgo pathGenOpts) error {
err := a.GenerateYangSchema(d, f, e)
if err != nil {
return err
Expand All @@ -23,7 +34,7 @@ func (a *App) PathCmdRun(d, f, e []string, search, withDescr, withPrefix, withTy
out := make(chan string)
defer close(out)
paths := make([]string, 0)
if search {
if pgo.search {
go gather(ctx, out, &paths)
} else {
go printer(ctx, out)
Expand All @@ -33,10 +44,22 @@ func (a *App) PathCmdRun(d, f, e []string, search, withDescr, withPrefix, withTy
collected = append(collected, collectSchemaNodes(entry, true)...)
}
for _, entry := range collected {
out <- a.generatePath(entry, withDescr, withPrefix, withTypes, pType)
if !pgo.stateOnly && !pgo.configOnly || pgo.stateOnly && pgo.configOnly {
out <- a.generatePath(entry, pgo.withDescr, pgo.withPrefix, pgo.withTypes, pgo.pathType)
continue
}
state := isState(entry)
if state && pgo.stateOnly {
out <- a.generatePath(entry, pgo.withDescr, pgo.withPrefix, pgo.withTypes, pgo.pathType)
continue
}
if !state && pgo.configOnly {
out <- a.generatePath(entry, pgo.withDescr, pgo.withPrefix, pgo.withTypes, pgo.pathType)
continue
}
}

if search {
if pgo.search {
p := promptui.Select{
Label: "select path",
Items: paths,
Expand Down Expand Up @@ -79,18 +102,40 @@ func (a *App) PathCmdRun(d, f, e []string, search, withDescr, withPrefix, withTy

func (a *App) PathPreRunE(cmd *cobra.Command, args []string) error {
a.Config.SetLocalFlagsFromFile(cmd)
if a.Config.PathSearch && a.Config.PathWithDescr {
return errors.New("flags --search and --descr cannot be used together")
}
if a.Config.LocalFlags.PathPathType != "xpath" && a.Config.LocalFlags.PathPathType != "gnmi" {
return fmt.Errorf("path-type must be one of 'xpath' or 'gnmi'")
return errors.New("path-type must be one of 'xpath' or 'gnmi'")
}
return a.yangFilesPreProcessing()
}

func (a *App) PathRunE(cmd *cobra.Command, args []string) error {
return a.PathCmdRun(
a.Config.GlobalFlags.Dir,
a.Config.GlobalFlags.File,
a.Config.GlobalFlags.Exclude,
pathGenOpts{
search: a.Config.LocalFlags.PathSearch,
withDescr: a.Config.LocalFlags.PathWithDescr,
withTypes: a.Config.LocalFlags.PathWithTypes,
withPrefix: a.Config.LocalFlags.PathWithPrefix,
pathType: a.Config.LocalFlags.PathPathType,
stateOnly: a.Config.LocalFlags.PathState,
configOnly: a.Config.LocalFlags.PathConfig,
},
)
}

func (a *App) InitPathFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&a.Config.LocalFlags.PathPathType, "path-type", "", "xpath", "path type xpath or gnmi")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathWithDescr, "descr", "", false, "print leaf description")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathWithPrefix, "with-prefix", "", false, "include module/submodule prefix in path elements")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathWithTypes, "types", "", false, "print leaf type")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathSearch, "search", "", false, "search through path list")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathState, "state-only", "", false, "generate paths only for YANG leafs representing state data")
cmd.Flags().BoolVarP(&a.Config.LocalFlags.PathConfig, "config-only", "", false, "generate paths only for YANG leafs representing config data")
cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) {
a.Config.FileConfig.BindPFlag(fmt.Sprintf("%s-%s", cmd.Name(), flag.Name), flag)
})
Expand Down Expand Up @@ -133,8 +178,7 @@ func (a *App) generatePath(entry *yang.Entry, withDescr, prefixTagging, withType
elementName = e.Prefix.Name + ":" + elementName
}
if e.Key != "" {
keylist := strings.Split(e.Key, " ")
for _, k := range keylist {
for _, k := range strings.Fields(e.Key) {
if prefixTagging && e.Prefix != nil {
k = e.Prefix.Name + ":" + k
}
Expand Down Expand Up @@ -266,3 +310,13 @@ func gather(ctx context.Context, c chan string, ls *[]string) {
}
}
}

func isState(e *yang.Entry) bool {
if e.Config == yang.TSFalse {
return true
}
if e.Parent != nil {
return isState(e.Parent)
}
return false
}
13 changes: 1 addition & 12 deletions cmd/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,7 @@ func newPathCmd() *cobra.Command {
"--dir": "DIR",
},
PreRunE: gApp.PathPreRunE,
RunE: func(cmd *cobra.Command, args []string) error {
return gApp.PathCmdRun(
gApp.Config.GlobalFlags.Dir,
gApp.Config.GlobalFlags.File,
gApp.Config.GlobalFlags.Exclude,
gApp.Config.LocalFlags.PathSearch,
gApp.Config.LocalFlags.PathWithDescr,
gApp.Config.LocalFlags.PathWithPrefix,
gApp.Config.LocalFlags.PathWithTypes,
gApp.Config.LocalFlags.PathPathType,
)
},
RunE: gApp.PathRunE,
PostRun: func(cmd *cobra.Command, args []string) {
cmd.ResetFlags()
gApp.InitPathFlags(cmd)
Expand Down
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ type LocalFlags struct {
PathWithPrefix bool `mapstructure:"path-with-prefix,omitempty" json:"path-with-prefix,omitempty" yaml:"path-with-prefix,omitempty"`
PathWithTypes bool `mapstructure:"path-types,omitempty" json:"path-types,omitempty" yaml:"path-types,omitempty"`
PathSearch bool `mapstructure:"path-search,omitempty" json:"path-search,omitempty" yaml:"path-search,omitempty"`
PathState bool `mapstructure:"path-state,omitempty" json:"path-state,omitempty" yaml:"path-state,omitempty"`
PathConfig bool `mapstructure:"path-config,omitempty" json:"path-config,omitempty" yaml:"path-config,omitempty"`
// Prompt
PromptFile []string `mapstructure:"prompt-file,omitempty" json:"prompt-file,omitempty" yaml:"prompt-file,omitempty"`
PromptExclude []string `mapstructure:"prompt-exclude,omitempty" json:"prompt-exclude,omitempty" yaml:"prompt-exclude,omitempty"`
Expand Down Expand Up @@ -183,6 +185,8 @@ type LocalFlags struct {
GeneratePathWithTypes bool `mapstructure:"generate-types,omitempty" json:"generate-types,omitempty" yaml:"generate-types,omitempty"`
GeneratePathSearch bool `mapstructure:"generate-search,omitempty" json:"generate-search,omitempty" yaml:"generate-search,omitempty"`
GeneratePathPathType string `mapstructure:"generate-path-path-type,omitempty" json:"generate-path-path-type,omitempty" yaml:"generate-path-path-type,omitempty"`
GeneratePathState bool `mapstructure:"generate-path-state,omitempty" json:"generate-path-state,omitempty" yaml:"generate-path-state,omitempty"`
GeneratePathConfig bool `mapstructure:"generate-path-config,omitempty" json:"generate-path-config,omitempty" yaml:"generate-path-config,omitempty"`
}

func New() *Config {
Expand Down
14 changes: 14 additions & 0 deletions docs/cmd/path.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### Description

With `path` command it is possible to generate and search through the XPATH style paths extracted from a YANG file.

By extracting the XPATH styled paths from a YANG model it is made possible to utilize CLI search tools like `awk`, `sed` and alike to find the paths satisfying specific matching rules.
Expand Down Expand Up @@ -28,6 +29,7 @@ The other option is `gnmi` which will result in the paths to be formatted using
```

#### search

With the `--search` flag present an interactive CLI search dialog is displayed that allows to navigate through the paths list and perform a search.

```bash
Expand All @@ -46,6 +48,18 @@ Use the arrow keys to navigate: ↓ ↑ → ← and : toggles search
↓ /state/aaa/radius/statistics/disconnect-messages/dropped/invalid
```
#### descr
When the `--descr` flag is present, the leaf description is printed after the path, indented with a `\t`.
#### config-only
When the `--config-only` flag is present, path are generated only for YANG leafs representing config data.
#### state-only
When the `--state-only` flag is present, path are generated only for YANG leafs representing state data.
### Examples
```bash
Expand Down

0 comments on commit 437d8ce

Please sign in to comment.