Skip to content
Snippets Groups Projects
Commit 34f56b4b authored by Manuel Kieweg's avatar Manuel Kieweg
Browse files

Merge branch 'path-traversal-demo' into '67-overhaul-architecture'

Path traversal demo

See merge request cocsn/gosdn!93
parents 1b779077 392c8b67
Branches
Tags
3 merge requests!93Path traversal demo,!91"Overhaul Architecture",!90Develop
Pipeline #60732 passed with warnings
Showing
with 134 additions and 2332 deletions
This diff is collapsed.
// Copyright (c) 2017 Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package gnmi
import (
"fmt"
"sort"
"strings"
pb "github.com/openconfig/gnmi/proto/gnmi"
)
// nextTokenIndex returns the end index of the first token.
func nextTokenIndex(path string) int {
var inBrackets bool
var escape bool
for i, c := range path {
switch c {
case '[':
inBrackets = true
escape = false
case ']':
if !escape {
inBrackets = false
}
escape = false
case '\\':
escape = !escape
case '/':
if !inBrackets && !escape {
return i
}
escape = false
default:
escape = false
}
}
return len(path)
}
// SplitPath splits a gnmi path according to the spec. See
// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-path-conventions.md
// No validation is done. Behavior is undefined if path is an invalid
// gnmi path. TODO: Do validation?
func SplitPath(path string) []string {
var result []string
if len(path) > 0 && path[0] == '/' {
path = path[1:]
}
for len(path) > 0 {
i := nextTokenIndex(path)
result = append(result, path[:i])
path = path[i:]
if len(path) > 0 && path[0] == '/' {
path = path[1:]
}
}
return result
}
// SplitPaths splits multiple gnmi paths
func SplitPaths(paths []string) [][]string {
out := make([][]string, len(paths))
for i, path := range paths {
out[i] = SplitPath(path)
}
return out
}
// StrPath builds a human-readable form of a gnmi path.
// e.g. /a/b/c[e=f]
func StrPath(path *pb.Path) string {
if path == nil {
return "/"
} else if len(path.Elem) != 0 {
return strPathV04(path)
} else if len(path.Element) != 0 {
return strPathV03(path)
}
return "/"
}
// strPathV04 handles the v0.4 gnmi and later path.Elem member.
func strPathV04(path *pb.Path) string {
b := &strings.Builder{}
for _, elm := range path.Elem {
b.WriteRune('/')
writeSafeString(b, elm.Name, '/')
if len(elm.Key) > 0 {
// Sort the keys so that they print in a conistent
// order. We don't have the YANG AST information, so the
// best we can do is sort them alphabetically.
keys := make([]string, 0, len(elm.Key))
for k := range elm.Key {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
b.WriteRune('[')
b.WriteString(k)
b.WriteRune('=')
writeSafeString(b, elm.Key[k], ']')
b.WriteRune(']')
}
}
}
return b.String()
}
// strPathV03 handles the v0.3 gnmi and earlier path.Element member.
func strPathV03(path *pb.Path) string {
return "/" + strings.Join(path.Element, "/")
}
// upgradePath modernizes a Path by translating the contents of the Element field to Elem
func upgradePath(path *pb.Path) *pb.Path {
if len(path.Elem) == 0 {
var elems []*pb.PathElem
for _, element := range path.Element {
n, keys, _ := parseElement(element)
elems = append(elems, &pb.PathElem{Name: n, Key: keys})
}
path.Elem = elems
path.Element = nil
}
return path
}
// JoinPaths joins multiple gnmi paths and returns a string representation
func JoinPaths(paths ...*pb.Path) *pb.Path {
var elems []*pb.PathElem
for _, path := range paths {
path = upgradePath(path)
elems = append(elems, path.Elem...)
}
return &pb.Path{Elem: elems}
}
func writeSafeString(b *strings.Builder, s string, esc rune) {
for _, c := range s {
if c == esc || c == '\\' {
b.WriteRune('\\')
}
b.WriteRune(c)
}
}
// ParseGNMIElements builds up a gnmi path, from user-supplied text
func ParseGNMIElements(elms []string) (*pb.Path, error) {
var parsed []*pb.PathElem
for _, e := range elms {
n, keys, err := parseElement(e)
if err != nil {
return nil, err
}
parsed = append(parsed, &pb.PathElem{Name: n, Key: keys})
}
return &pb.Path{
Element: elms, // Backwards compatibility with pre-v0.4 gnmi
Elem: parsed,
}, nil
}
// parseElement parses a path element, according to the gNMI specification. See
// https://github.com/openconfig/reference/blame/master/rpc/gnmi/gnmi-path-conventions.md
//
// It returns the first string (the current element name), and an optional map of key name
// value pairs.
func parseElement(pathElement string) (string, map[string]string, error) {
// First check if there are any keys, i.e. do we have at least one '[' in the element
name, keyStart := findUnescaped(pathElement, '[')
if keyStart < 0 {
return name, nil, nil
}
// Error if there is no element name or if the "[" is at the beginning of the path element
if len(name) == 0 {
return "", nil, fmt.Errorf("failed to find element name in %q", pathElement)
}
// Look at the keys now.
keys := make(map[string]string)
keyPart := pathElement[keyStart:]
for keyPart != "" {
k, v, nextKey, err := parseKey(keyPart)
if err != nil {
return "", nil, err
}
keys[k] = v
keyPart = nextKey
}
return name, keys, nil
}
// parseKey returns the key name, key value and the remaining string to be parsed,
func parseKey(s string) (string, string, string, error) {
if s[0] != '[' {
return "", "", "", fmt.Errorf("failed to find opening '[' in %q", s)
}
k, iEq := findUnescaped(s[1:], '=')
if iEq < 0 {
return "", "", "", fmt.Errorf("failed to find '=' in %q", s)
}
if k == "" {
return "", "", "", fmt.Errorf("failed to find key name in %q", s)
}
rhs := s[1+iEq+1:]
v, iClosBr := findUnescaped(rhs, ']')
if iClosBr < 0 {
return "", "", "", fmt.Errorf("failed to find ']' in %q", s)
}
if v == "" {
return "", "", "", fmt.Errorf("failed to find key value in %q", s)
}
next := rhs[iClosBr+1:]
return k, v, next, nil
}
// findUnescaped will return the index of the first unescaped match of 'find', and the unescaped
// string leading up to it.
func findUnescaped(s string, find byte) (string, int) {
// Take a fast track if there are no escape sequences
if strings.IndexByte(s, '\\') == -1 {
i := strings.IndexByte(s, find)
if i < 0 {
return s, -1
}
return s[:i], i
}
// Find the first match, taking care of escaped chars.
var b strings.Builder
var i int
len := len(s)
for i = 0; i < len; {
ch := s[i]
if ch == find {
return b.String(), i
} else if ch == '\\' && i < len-1 {
i++
ch = s[i]
}
b.WriteByte(ch)
i++
}
return b.String(), -1
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -4,23 +4,23 @@ go 1.14 ...@@ -4,23 +4,23 @@ go 1.14
require ( require (
code.fbi.h-da.de/cocsn/swagger/apis v0.0.0-20200924152423-61030cab7b88 code.fbi.h-da.de/cocsn/swagger/apis v0.0.0-20200924152423-61030cab7b88
code.fbi.h-da.de/cocsn/yang-models v0.0.3 code.fbi.h-da.de/cocsn/yang-models v0.0.4
github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a code.fbi.h-da.de/cocsn/yang-modules/generated/tapi v0.0.0-20201116134549-765aa1790752
github.com/BurntSushi/toml v0.3.1
github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591 github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591
github.com/go-openapi/runtime v0.19.22 github.com/go-openapi/runtime v0.19.22
github.com/go-openapi/strfmt v0.19.5 github.com/go-openapi/strfmt v0.19.5
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
github.com/google/uuid v1.1.2
github.com/neo4j/neo4j-go-driver v1.8.3 github.com/neo4j/neo4j-go-driver v1.8.3
github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802 github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696 github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696
github.com/openconfig/ygot v0.10.0 github.com/openconfig/ygot v0.10.0
github.com/openconfig/goyang v0.2.2
github.com/rivo/tview v0.0.0-20201018122409-d551c850a743 github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/spf13/viper v1.7.1
github.com/tidwall/gjson v1.6.3 github.com/tidwall/gjson v1.6.3
golang.org/x/net v0.0.0-20200904194848-62affa334b73 golang.org/x/net v0.0.0-20200904194848-62affa334b73
google.golang.org/grpc v1.29.1 google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.23.0
) )
This diff is collapsed.
gosdn.png

132 KiB

This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package interfaces
// Client provides an interface for
// SBI protocol clients
type Client interface {
GetConfig() ClientConfig
}
package nucleus package interfaces
// ClientConfig contains SBI ciena // ClientConfig contains SBI client
// configuration parameters // configuration parameters
// Deprecated in favor of spf viper // Deprecated in favor of spf viper
type ClientConfig struct { type ClientConfig struct {
......
This diff is collapsed.
This diff is collapsed.
package nucleus
import "context"
type Restconf struct {
}
func (rc *Restconf) SetConfig(interface{}) error {
return nil
}
func (rc *Restconf) GetConfig() interface{} {
return nil
}
func (rc *Restconf) Subscribe(ctx context.Context, params ...string) error {
return nil
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment