gNOI in Golang
gNOI review
These are a few examples leveraging golang and gNOI using the gNOI protobuf specifically the System service
The following examples show how to leverage the ping rpc and traceroute rpc
All code can be found within the src directory under gnoi
We will be leveraging the gNOI godocs which module can be imported as github.com/openconfig/gnoi
Each one of the examples has the following default flags which can be changed based on the environment.
Test Device configuration
cd into src/gnoi
The directory should include the go.mod/go.sum for the correct packages so nothing needs installed on the system at the current time.
Run ping.go
src/gnoi/ping.go
Reveal output
package main
import (
"context"
"flag"
"fmt"
"os"
"time"
log "github.com/golang/glog"
system "github.com/openconfig/gnoi/system"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
func checkflags(flag ...string) {
for _, f := range flag {
if f == "" {
fmt.Printf("You have an empty flag please fix.")
os.Exit(1)
}
}
}
func main() {
// Add input parameters
username := flag.String("username", "admin", "username for connection to gNOI")
password := flag.String("password", "admin", "password for connection to gNOI")
target := flag.String("target", "", "Target ip or hostname of the device running gNOI")
destination := flag.String("destination", "", "Destination of the address to ping to")
flag.Parse()
// Check for empty flags.
checkflags(*username, *password, *target, *destination)
conn, err := grpc.Dial(*target, grpc.WithInsecure())
if err != nil {
log.Exitf("Failed to %s Error: %v", target, err)
}
defer conn.Close()
// Create the new grpc service connection
Sys := system.NewSystemClient(conn)
// pass in context blank information with the timeout.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
// cancel when the function is over.
defer cancel()
// Since Metadata needs a map to pass into the header of gRPC request create a map for it.
metamap := make(map[string]string)
// Set the username and password
metamap["username"] = *username
metamap["password"] = *password
// Set the metadata needed in the metadata package
md := metadata.New(metamap)
// set the ctx to use the metadata in every update.
ctx = metadata.NewOutgoingContext(ctx, md)
// Try to ping 10 times with a loop
for i := 0; i < 10; i++ {
response, err := Sys.Ping(ctx, &system.PingRequest{Destination: *destination})
if err != nil {
log.Fatalf("Error trying to ping: %v", err)
}
fmt.Println(response.Recv())
}
}
Output
go run ping/ping.go -username admin -password admin -target 172.20.20.2:6030 -destination 2.2.2.2
source:"2.2.2.2" time:38000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:44000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:37000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:41000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:40000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:38000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:40000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:36000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:44000 bytes:64 sequence:1 ttl:64 <nil>
source:"2.2.2.2" time:66000 bytes:64 sequence:1 ttl:64 <nil>
Run traceroute.go
src/gnoi/traceroute.go
Reveal output
package main
import (
"context"
"flag"
"fmt"
"os"
"time"
log "github.com/golang/glog"
system "github.com/openconfig/gnoi/system"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
func checkflags(flag ...string) {
for _, f := range flag {
if f == "" {
fmt.Printf("You have an empty flag please fix.")
os.Exit(1)
}
}
}
func main() {
// Add input parameters
username := flag.String("username", "", "username for connection to gNOI")
password := flag.String("password", "", "password for connection to gNOI")
target := flag.String("target", "", "Target ip or hostname of the device running gNOI")
destination := flag.String("destination", "", "Destination of the address to traceroute to")
flag.Parse()
conn, err := grpc.Dial(*target, grpc.WithInsecure())
if err != nil {
log.Exitf("Failed to %s Error: %v", target, err)
}
defer conn.Close()
// Check for empty flags.
checkflags(*username, *password, *target, *destination)
// Create the new grpc service connection
Sys := system.NewSystemClient(conn)
// pass in context blank information with the timeout.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
// cancel when the function is over.
defer cancel()
// Since Metadata needs a map to pass into the header of gRPC request create a map for it.
metamap := make(map[string]string)
// Set the username and password
metamap["username"] = *username
metamap["password"] = *password
// Set the metadata needed in the metadata package
md := metadata.New(metamap)
// set the ctx to use the metadata in every update.
ctx = metadata.NewOutgoingContext(ctx, md)
response, err := Sys.Traceroute(ctx, &system.TracerouteRequest{Destination: *destination})
if err != nil {
log.Fatalf("Cannot trace path: %v", err)
}
fmt.Println(response.Recv())
}
Output