Git Product home page Git Product logo

gnxi's Introduction

License GoDoc Go Report Card Build Status Code coverage master

gNxI Tools

  • gNMI - gRPC Network Management Interface
  • gNOI - gRPC Network Operations Interface

A collection of tools for Network Management that use the gNMI and gNOI protocols.

Summary

Notes about these tools:

  • They are intended for testing and as reference implementation of the protocol.
  • They log to stderr by default, disable with -logtostderr=false.
  • They use glog's log levels, use -v 1 to log proto message exchanges.

gNMI Clients:

gNMI Targets:

gNOI Clients

gNOI Targets

Helpers

Documentation

Getting Started

These instructions will get you a copy of the project up and running on your local machine.

Prerequisites

Install go in your system https://golang.org/doc/install. Requires golang1.14+.

Download sources

go get github.com/google/gnxi
ls $GOPATH/src/github.com/google/gnxi

Building and installing binaries

cd $GOPATH
mkdir bin
# This reads the go modules dependencies for installation
cd src/github.com/google/gnxi
go install ./...
ls -la $GOPATH/bin

Generating certificates

cd $GOPATH/bin
./../src/github.com/google/gnxi/certs/generate.sh

Running a client

cd $GOPATH/bin
./gnoi_reset \
    -target_addr localhost:9339 \
    -target_name target.com \
    -rollback_os \
    -zero_fill \
    -key client.key \
    -cert client.crt \
    -ca ca.crt

Optionally define $GOBIN as $GOPATH/bin and add it to your path to run the binaries from any folder.

export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN

Disclaimer

gnxi's People

Contributors

alisharif2 avatar boleifu avatar cpubob avatar dependabot[bot] avatar donnewtonintel avatar ericm avatar georgeh049 avatar jared-mullin avatar joseignaciotamayo avatar kgoralski avatar larryleguo avatar loriscn12 avatar maheshnayak1 avatar markuscraig avatar mike-albano avatar mpsalisbury avatar olivier-leduc avatar phani2410 avatar pkthapa avatar reshad-rahman avatar river8 avatar robshakir avatar samribeiro avatar tejaskumark avatar tony-vanderpeet avatar viardant avatar wenovus avatar xavier-contreras avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gnxi's Issues

too many arguments in call to ytypes.Unmarshal

@larryleguo @samribeiro
Hi
When we try to build the gnmi project and gnmi target (I need gnmi target which is dependent to gnmi package) using Go modules or dep, we get an error like this:

pkg/gnmi/modeldata/gostruct/generated.go:71:63: undefined: ytypes.UnmarshalOpt
pkg/gnmi/modeldata/gostruct/generated.go:81:25: too many arguments in call to ytypes.Unmarshal

Any ideas? It looks like there are some conflicts somewhere.

Add support for Origin.

Add support, via flag, for the gNMI Origin in gnmi_set. This will disambiguate the namespace when a vendor utilizes both OpenConfig and rfc7951 (or otherwise vendor-specific) YANG modules.

When sending OpenConfig JSON, the origin key will have a value of "openconfig".

Log message for missing target name

The following should say "Must set a Common Name ID with -target_name."

if *targetCN == "" {
	log.Exit("Must set a Common Name ID with -targetCN.")
}

Refactor certificate usage for the binaries.

  • CA.crt -> Certificate Authority certificate (usually a self-signed certificate that signs all the others).
  • CA.key -> CA Private key (usually should be kept very secret).
  • client.crt/target.crt -> A client or target certificate that was signed by the CA.
  • client.key/target.key -> The private key corresponding to the client or target.

Short (oversimplified) summary for how certificates are used to authenticate the client and the target in gRPC

Before Authentication

  • The client has: client.crt, client.key, CA.crt
  • The target has: target.crt, target.key, CA.crt

During Authentication

  • The client sends the client certificate to the target.
  • The target sends the target certificate to the client.
  • The client uses the CA certificate to validate that the received target certificate is valid.
  • The target uses the CA certificate to validate that the received client certificate is valid.
  • The client verifyes that the name in the target certificate matches with the expected one.

After Authentication

  • The private keys are used for establishing the secure channels.

Current certificate usage for the binaries

The following binaries receive ca.crt, client.crt/target.crt, client.key/target.key:
gnmi_get
gnmi_set
gnmi_target
gnoi_reset

However, gnoi_cert, receives ca.crt and ca.key. This is usefull because this client needs to sign and install certificates in the target. In addition, gnoi_cert uses this ca.crt and key to dynamically create a client.crt to connect to the target.

Proposed certificate usage for all binaries

Have all binaries accept one of the two options:

  1. ca.crt, client.crt/target.crt, client.key/target.key;
    or
  2. ca.key, ca.crt;

Package these two options in a library under utils where it can be used by all other binaries.

Create gNOI OS Client

This issue consists of building client for testing the gNOI OS service implementation.

As part of this client implementation, the following gNOI OS service operations will be tested:

  1. Installing the Operating System
  2. Activating the Operating System
  3. Verifying the Operating System

Getting subtree encoded as JSON in one update message

Hi guys, I have question regarding encoding of data. According to gNMI specification, section 2.3.1, I assumed, that when I will send get request to target, with a path which does not point to leaf node, then in response message will be one notification with one update message which value will be JSON encoded subtree located under this path.

But instead in response message I receive notification message with separate update message for each leaf node in that subtree. My question is, if I am missing something from official gNMI specification, or I had to setup gnxi target in some special way in order to receive whole subtree as JSON encoded value of one update message.

Question about gnmi_get and Unmarsha JSON_IETF

I am using GetJsonIetfVal()on pb.Update inside a GetRespose.Notification and, I am able to the JSON payload coming back from the node.
Is there a method to Unmarshell and assign this payload to YANG go struct (ygot generated bindings)? I am not able to see the go struct getting populated with the JSON data.

For example,
gNMI Get for xPath "openconfig-interfaces:interfaces/"

for _, pbNotification := range GetRespose.Notification {
	for _, update := range pbNotification.GetUpdate() {
		InterfaceByteVal := val.GetJsonIetfVal() <<<<<<<<<<<<<

ocInterface := &yangmodels.Interface{} // /openconfig-interfaces/interfaces/interface YANG schema element.

err = json.Unmarshal(InterfaceByteVal, ocInterface)

Create gNOI OS Mock File Generator

We need to be able to generate a mock OS file for testing purposes. The generator should embed the OS version and a hash for verification purposes.

Why gnmi_get work, but py_gnmicli.py NOT work ?

Hi all,

I write gnmi server follow SONiC/TELEMETRY. The server side start command use '--insecure', which is:

/usr/sbin/telemetry -logtostderr --log_to_syslog=true --insecure --port 8080 --allow_no_client_auth -v=2

And server side is written by GO, using "google.golang.org/grpc"

And I use gnmi_get as gnmi client, and it works, like this:

gyw@sonic107:~/go/src/github.com/google/gnxi/gnmi_get$ gnmi_get -xpath_target "MTNOS" -xpath "/interfaces/interface[name=Ethernet16]" -target_addr 172.18.8.241:8080 -alsologtostderr -insecure true
== getRequest:
prefix: <
  target: "MTNOS"
>
path: <
  elem: <
    name: "interfaces"
  >
  elem: <
    name: "interface"
    key: <
      key: "name"
      value: "Ethernet16"
    >
  >
>
encoding: JSON_IETF

== getResponse:
notification: <
  prefix: <
    target: "MTNOS"
  >
  update: <
    path: <
      elem: <
        name: "interfaces"
      >
      elem: <
        name: "interface"
        key: <
          key: "name"
          value: "Ethernet16"
        >
      >
    >
    val: <
      json_ietf_val: "{\"admin_status\":2,\"enabled\":{},\"oper_status\":3}"
    >
  >
>

And this is written by GO, using "google.golang.org/grpc"

But when I change to py_gnmicli.py, it NOT work, like this, WHY ???

gyw@sonic107:~/go/src/github.com/google/gnxi/gnmi_cli_py$ python3 py_gnmicli.py -m get -t 172.18.8.241 -p 8080 -x "/interfaces/interface[name=Ethernet16]"  -n
Performing GetRequest, encoding=JSON_IETF to 172.18.8.241  with the following gNMI Path
 -------------------------
 elem {
  name: "interfaces"
}
elem {
  name: "interface"
  key {
    key: "name"
    value: "Ethernet16"
  }
}

Traceback (most recent call last):
  File "py_gnmicli.py", line 415, in <module>
    main()
  File "py_gnmicli.py", line 384, in main
    response = _get(stub, paths, user, password)
  File "py_gnmicli.py", line 277, in _get
    return stub.Get(gnmi_pb2.GetRequest(path=[paths], encoding='JSON_IETF'))
  File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 550, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/usr/local/lib/python3.5/dist-packages/grpc/_channel.py", line 467, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNAVAILABLE
	details = "Socket closed"
	debug_error_string = "{"created":"@1590563380.688673642","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1036,"grpc_message":"Socket closed","grpc_status":14}"
>

And this is written by PYTHON, using "grpc"

Then I capture TCP message using tcpdump, I found:

  1. It's TCP message, NOT GRPC message (this is show by wireshark, maybe wireshark is wrong?), when I use gnmi_get as client to send gRPC request.
  2. It's GRPC message(this is show by wireshark), when I use py_gnmicli.py as client to send gRPC request.

Install/Rotate: certificate-id not set in GenerateCSR msg

https://github.com/google/gnxi/blob/master/gnoi/cert/client.go#L138 does not set the CertificateId field in GenerateCSR, instead the CertificateId field is set in LoadCertificateRequest: https://github.com/google/gnxi/blob/master/gnoi/cert/client.go#L189. According to https://github.com/google/gnxi/blob/master/gnoi/cert/pb/cert.proto#L203, it should be set in GenerateCSR and according to https://github.com/google/gnxi/blob/master/gnoi/cert/pb/cert.proto#L269 it should only be set in LoadCertificateRequest when the KeyPair is provided by the client (which isn't the case here since KeyPair is nil.

Similar issue in Rotate() function

Issues with xpath

Hello,

I'm facing two issues with the xpath parsing both resulting in a "xpath component parse error".

It seems that '-' are not supported in the xpath when used for a key like in:
--xpath '/state/chassis[chassis-number=1]/name/'
It results in a "main.XpathError: xpath component parse error: chassis[chassis-number=1]".

It seems that '/' are stripped from the xpath, even when used as a key value like in:
--xpath '/state/port[port_id=1/1/1]/statistics/out-packets'
It results in a "main.XpathError: xpath component parse error: port[port_id=1"

(I cross-checked the xpath syntax with gnmi_get, which does not give errors on the xpaths described above)

Any ideas ?

Thanks,
Oli

JSON encoding not supported for leaf-nodes

Hi,

1. I have problem to set leaf node with with json_val.

sending update request:

update {
  path {
    elem {
      name: "system"
    }
    elem {
      name: "config"
    }
    elem {
      name: "domain-name"
    }
  }
  val {
    json_val: "domain-name.com"
  }
}

returns error: INTERNAL: cannot convert leaf node to scalar type: non-scalar type &{JsonVal:[100 111 109 97 105 110 45 110 97 109 101 46 99 111 109]}

The specification tells that the value node should be encoded by oneof the scalar types or structural types ... .

Also in the 2.3.1 JSON and JSON_IETF there is example how string or uint32 leaf-node can be serialized.

So I think the server should be able to apply also scalar type

val {
  string_val: "domain-name.com"
}

but also JSON type

val {
  json_val: "domain-name.com"
}

2. Also the server does not return json_val for leaf-nodes.
When the encoding is explicitly specified in get request:

path {
  elem {
    name: "system"
  }
  elem {
    name: "config"
  }
  elem {
    name: "domain-name"
  }
}
encoding: JSON_IETF

It returns val as string_val. I would expect json_val.

notification {
  timestamp: 1532431023993295089
  update {
    path {
      elem {
        name: "system"
      }
      elem {
        name: "config"
      }
      elem {
        name: "domain-name"
      }
    }
    val {
      string_val: "domain-name.com"
    }
  }
}

Same response returned even when encoding is not specified.
The specification tells that If the client does not specify the encoding in an RPC message, it MUST send JSON encoded values (the default encoding). So I would expect to get at least json_val also when no encoding was specified.

Or did I understand it wrong? Please correct me if so.

Create gNOI Reset Mocked Target

This issue consists of building a mocked target for testing the gNOI Reset client implementation.

As part of this mocked target implementation, the following gNOI Reset client operations will be tested:

Start a Factory Reset

How to set Path prefix Elements in gnmi_get

I would like to give the prefix path and set the Elem field in below structure using gnmi_get.
p prefix
*github.com/openconfig/gnmi/proto/gnmi.Path {
Element: []string len: 0, cap: 0, nil,
Origin: "",
Elem: []*github.com/openconfig/gnmi/proto/gnmi.PathElem len: 0, cap: 0, nil,
Target: "CONFIG_DB",
XXX_NoUnkeyedLiteral: struct {} {},
XXX_unrecognized: []uint8 len: 0, cap: 0, nil,
XXX_sizecache: 0,}

Create gNOI OS Mocked Target

This issue consists of building a mocked target for testing the gNOI OS client implementation.

As part of this mocked target implementation, the following gNOI OS client operations will be tested:

Installing the Operating System
Activating the Operating System
Verifying the Operating System

Yaml format support

Hi,
I made a yang model for yaml configuration file, and I want to send a yaml file instead of json file. Is it an easy task to support yaml format?
Which files need to be changed?

Thank you,

Create gNOI Reset Client

This issue consists of building client for testing the gNOI Reset service implementation.

As part of this client implementation, the following gNOI Reset service operations will be tested:

Start a Factory Reset

which version of openconfig yang models

Hi,
which version of openconfig yang models do you actually support or is intended to support?

There are kind of old version values for openconfig yang models in gnxi/gnmi/modeldata/modeldata.go. But it looks that model was actually generated from the current master of openconfig repository.

So, are the version values in gnxi/gnmi/modeldata/modeldata.go wrong?

xpath (key, value) does not support '/'

The split of xpath string is done with '/' as separator.
If the (value) of a key contains a '/', it breaks.
Example (from a router): '/state/port[port-id=1/1/1]/statistics/out-packets'

To work-around the issue, I've modified the code, using a function that does not split inside parenthesis.
(code piece that I found on stackoverflow)
It is then used in the _path_names(xpath).

If you think it's a good work-around, please include.
Or let me know how to do it better :-)

See below:

def parenthesis_split(sentence,separator='/',lparen='[',rparen=']'):
"""Split string based on separator, avoiding split inside parenthesis
"""
nb_brackets=0
sentence = sentence.strip(separator) # get rid of leading/trailing seps

l=[0]
for i,c in enumerate(sentence):
    if c==lparen:
        nb_brackets+=1
    elif c==rparen:
        nb_brackets-=1
    elif c==separator and nb_brackets==0:
        l.append(i)
    # handle malformed string
    if nb_brackets<0:
        raise Exception("Syntax error")

l.append(len(sentence))
# handle missing closing parentheses
if nb_brackets>0:
    raise Exception("Syntax error")

return([sentence[i:j].strip(separator) for i,j in zip(l,l[1:])])

def _path_names(xpath):
"""Parses the xpath names.

This takes an input string and converts it to a list of gNMI Path names. Those
are later turned into a gNMI Path Class object for use in the Get/SetRequests.
Args:
xpath: (str) xpath formatted path.

Returns:
list of gNMI path names.
"""
if not xpath or xpath == '/': # A blank xpath was provided at CLI.
return []

return parenthesis_split(xpath.strip().strip('/'),'/','[',']') # Remove leading and trailing '/'.

Decouple osPb.InstallResponse_InstallError from mockos.go

gnxi/utils/mockos/mockos.go:ValidateOS() should be decoupled form *osPb.InstallResponse_InstallError

This way the utility can be made more generic.

suggestion:

  • return only os
  • if parse fails return nil

in caller:

  • check if hash is good
  • check if incompatible

requesting leaf-list element

Hello,
why I can get leaf-node element, e.g.:

path {
  elem {
    name: "system"
  }
  elem {
    name: "aaa"
  }
  elem {
    name: "authentication"
  }
  elem {
    name: "admin-user"
  }
  elem {
    name: "config"
  }
  elem {
    name: "admin-password"
  }
}

but can not get leaf-list element:

path {
  elem {
    name: "system"
  }
  elem {
    name: "aaa"
  }
  elem {
    name: "authentication"
  }
  elem {
    name: "config"
  }
  elem {
    name: "authentication-method"
  }
}

returns: INTERNAL: unexpected kind of leaf node type: [0xc420451998 0xc420451a08] slice

It this a bug or it should work like this?

Thanks.

gnmi_target build fails

server_test.go:49: error in creating server: nil schema for type *gostruct.Device, value &{<nil> <nil> <nil>}

Project Not building with GO 1.8.x

Travis is not able to execute test Scripts. The environment is not being setup.

Following errors are coming up:

# golang.org/x/net/http2
../../../golang.org/x/net/http2/server.go:220: s.RegisterOnShutdown undefined (type *http.Server has no field or method RegisterOnShutdown)

# google.golang.org/grpc/internal/syscall
../../../google.golang.org/grpc/internal/syscall/syscall_linux.go:79: tcpconn.SyscallConn undefined (type *net.TCPConn has no field or method SyscallConn)
../../../google.golang.org/grpc/internal/syscall/syscall_linux.go:100: tcpconn.SyscallConn undefined (type *net.TCPConn has no field or method SyscallConn)


# google.golang.org/grpc/credentials/internal
../../../google.golang.org/grpc/credentials/internal/syscallconn.go:29: syntax error: unexpected = in type declaration

Seems like this issue is because of Go 1.8.x support. Please check.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.