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

Simple HTTP API and CLI

parent 91208d20
No related branches found
No related tags found
1 merge request!90Develop
package cli
import (
"fmt"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net/http"
"strings"
)
const apiRoot = "/api?"
var builder *strings.Builder
func init() {
builder = &strings.Builder{}
}
func HttpGet(apiEndpoint, f string, args ...string) error {
for _, p := range args {
builder.WriteString("&")
builder.WriteString(p)
}
resp, err := http.Get(apiEndpoint + apiRoot + "q=" + f + builder.String())
if err != nil {
return err
}
builder.Reset()
switch resp.StatusCode {
case http.StatusOK:
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println(string(bytes))
case http.StatusCreated:
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println(string(bytes))
default:
log.WithFields(log.Fields{
"status code": resp.StatusCode,
}).Error("operation unsuccessful")
}
return nil
}
......@@ -4,16 +4,13 @@ import (
"code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi"
oc "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
"context"
"github.com/google/gnxi/utils/credentials"
pb "github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/goyang/pkg/yang"
"github.com/openconfig/ygot/util"
"github.com/openconfig/ygot/ygot"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/reflection"
"google.golang.org/grpc/status"
"net"
"reflect"
)
......@@ -39,12 +36,6 @@ func newServer(model *gnmi.Model, config []byte) (*server, error) {
// Get overrides the Get func of gnmi.Target to provide user auth.
func (s *server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
msg, ok := credentials.AuthorizeUser(ctx)
if !ok {
log.Infof("denied a Get request: %v", msg)
return nil, status.Error(codes.PermissionDenied, msg)
}
log.Infof("allowed a Get request: %v", msg)
return s.Server.Get(ctx, req)
}
......@@ -64,7 +55,7 @@ func (s *server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse,
// Target starts a gNMI target listening on the specified port.
func Target(bindAddr string) error {
entries := make([]*yang.Entry, 0)
for _,e := range oc.SchemaTree {
for _, e := range oc.SchemaTree {
entries = append(entries, e)
}
......
package cli
import (
log "github.com/golang/glog"
"github.com/openconfig/ygot/util"
log "github.com/sirupsen/logrus"
)
func LeafPaths() error {
for _,v := range testSchema.SchemaTree {
for _, v := range testSchema.SchemaTree {
entry, err := util.FindLeafRefSchema(v, "/interface/")
if err != nil {
log.Error(err)
......@@ -14,4 +14,4 @@ func LeafPaths() error {
log.Info(entry)
}
return nil
}
\ No newline at end of file
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// addDeviceCmd represents the addDevice command
var addDeviceCmd = &cobra.Command{
Use: "add-device",
Short: "adds a device to the controller",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(
apiEndpoint,
"addDevice",
"address="+address,
"password="+password,
"username="+username,
)
},
}
func init() {
cliCmd.AddCommand(addDeviceCmd)
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"errors"
"github.com/spf13/cobra"
)
var uuid string
var apiEndpoint string
// cliCmd represents the cli command
var cliCmd = &cobra.Command{
Use: "cli",
Short: "",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return errors.New("no subcommand provided")
},
}
func init() {
rootCmd.AddCommand(cliCmd)
cliCmd.PersistentFlags().StringVar(&uuid, "uuid", "", "uuid of the requested device")
cliCmd.PersistentFlags().StringVar(&apiEndpoint, "api-endpoint", "http://localhost:8080", "address of the target")
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// cliSetCmd represents the cliSet command
var cliSetCmd = &cobra.Command{
Use: "set",
Short: "set a value on a device",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(
apiEndpoint,
"set",
"uuid="+uuid,
"path="+args[0],
"address="+address,
"value="+args[1],
)
},
}
func init() {
cliCmd.AddCommand(cliSetCmd)
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// getDeviceCmd represents the getDevice command
var getDeviceCmd = &cobra.Command{
Use: "get-device",
Short: "gets device information from the controller",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(apiEndpoint, "getDevice", "uuid="+uuid)
},
}
func init() {
cliCmd.AddCommand(getDeviceCmd)
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// getIdsCmd represents the getIds command
var getIdsCmd = &cobra.Command{
Use: "get-ids",
Short: "gets device IDs from the controller",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(apiEndpoint, "getIDs")
},
}
func init() {
cliCmd.AddCommand(getIdsCmd)
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// requestCmd represents the request command
var requestCmd = &cobra.Command{
Use: "request",
Short: "requests a path from a specified device on the controller",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(apiEndpoint, "request", "uuid="+uuid, "path="+args[0])
},
}
func init() {
cliCmd.AddCommand(requestCmd)
}
/*
Copyright © 2021 da/net research group <danet.fbi.h-da.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/cli"
"github.com/spf13/cobra"
)
// requestAllCmd represents the requestAll command
var requestAllCmd = &cobra.Command{
Use: "request-all",
Short: "requests specified path from all devices on the controller",
Long: ``,
RunE: func(cmd *cobra.Command, args []string) error {
return cli.HttpGet(apiEndpoint, "requestAll", "path="+args[0])
},
}
func init() {
cliCmd.AddCommand(requestAllCmd)
}
......@@ -31,16 +31,14 @@ POSSIBILITY OF SUCH DAMAGE.
package cmd
import (
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"os"
"github.com/spf13/viper"
)
"code.fbi.h-da.de/cocsn/gosdn/nucleus"
"context"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"os"
"github.com/spf13/viper"
)
var cfgFile string
var username string
......@@ -49,79 +47,74 @@ var address string
var loglevel string
var grpcPort string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "gosdn",
Short: "starts the gosdn controller",
Long: `Set GOSDN_DEBUG environment variable to enalbe debug logging.`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
return nucleus.Run(ctx)
},
Use: "gosdn",
Short: "starts the gosdn controller",
Long: `Set GOSDN_DEBUG environment variable to enalbe debug logging.`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
return nucleus.Run(ctx)
},
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
log.WithFields(log.Fields{
}).Error(err)
os.Exit(1)
}
if err := rootCmd.Execute(); err != nil {
log.WithFields(log.Fields{}).Error(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
cobra.OnInitialize(initConfig)
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./configs/gosdn.toml)")
rootCmd.PersistentFlags().StringVarP(&username, "username", "u", "admin", "username for a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&password, "password", "p", "arista", "password for a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&username, "address", "a", "ceos-cocsn.apps.ocp.fbi.h-da.de:6030", "address to a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&loglevel, "log-level", "l", "", "log level 'debug' or 'trace'")
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./configs/gosdn.toml)")
rootCmd.PersistentFlags().StringVarP(&username, "username", "u", "admin", "username for a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&password, "password", "p", "arista", "password for a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&address, "address", "a", "ceos-cocsn.apps.ocp.fbi.h-da.de:6030", "address to a gnmi resource")
rootCmd.PersistentFlags().StringVarP(&loglevel, "log-level", "l", "", "log level 'debug' or 'trace'")
rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "55055", "port for gRPC NBI")
rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "55055", "port for gRPC NBI")
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath("./configs")
viper.AddConfigPath("/usr/local/etc/gosdn/")
viper.SetConfigType("toml")
viper.SetConfigName("gosdn")
}
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
viper.SetDefault("socket", ":" + grpcPort)
loglevel = viper.GetString("GOSDN_LOG")
log.SetReportCaller(true)
switch loglevel {
case "trace":
log.SetLevel(log.TraceLevel)
case "debug":
log.SetLevel(log.DebugLevel)
default:
log.SetLevel(log.InfoLevel)
log.SetFormatter(&log.JSONFormatter{})
log.SetReportCaller(false)
}
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath("./configs")
viper.AddConfigPath("/usr/local/etc/gosdn/")
viper.SetConfigType("toml")
viper.SetConfigName("gosdn")
}
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
log.Debug("Using config file:", viper.ConfigFileUsed())
}
viper.SetDefault("socket", ":"+grpcPort)
loglevel = viper.GetString("GOSDN_LOG")
log.SetReportCaller(true)
switch loglevel {
case "trace":
log.SetLevel(log.TraceLevel)
case "debug":
log.SetLevel(log.DebugLevel)
default:
log.SetLevel(log.InfoLevel)
log.SetFormatter(&log.JSONFormatter{})
log.SetReportCaller(false)
}
}
......@@ -42,7 +42,7 @@ var heartbeatInterval int64
var subscribeCmd = &cobra.Command{
Use: "subscribe",
Short: "subscribe to target",
Long: `Starts a gNMI subscriber requersting the specified paths on the target and logs the response to stdout.
Long: `Starts a gNMI subscriber requesting the specified paths on the target and logs the response to stdout.
Only 'stream' mode with 'sample' operation supported.`,
RunE: func(cmd *cobra.Command, args []string) error {
......@@ -53,6 +53,6 @@ var subscribeCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(subscribeCmd)
subscribeCmd.Flags().Int64Var(&sampleInterval, "sample-rate", 5, "Sample rate per second.")
subscribeCmd.Flags().Int64Var(&heartbeatInterval, "heartbeat-rate", 1, "Heartbeat rate per second.")
subscribeCmd.Flags().Int64Var(&sampleInterval, "sample-rate", 5, "Sample rate per second.")
subscribeCmd.Flags().Int64Var(&heartbeatInterval, "heartbeat-rate", 1, "Heartbeat rate per second.")
}
/* Copyright 2017 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package modeldata contains the following model data in gnmi proto struct:
// openconfig-interfaces 2.0.0,
// openconfig-openflow 0.1.0,
// openconfig-platform 0.5.0,
// openconfig-system 0.2.0.
package modeldata
import (
pb "github.com/openconfig/gnmi/proto/gnmi"
)
const (
// OpenconfigInterfacesModel is the openconfig YANG model for interfaces.
OpenconfigInterfacesModel = "openconfig-interfaces"
// OpenconfigOpenflowModel is the openconfig YANG model for openflow.
OpenconfigOpenflowModel = "openconfig-openflow"
// OpenconfigPlatformModel is the openconfig YANG model for platform.
OpenconfigPlatformModel = "openconfig-platform"
// OpenconfigSystemModel is the openconfig YANG model for system.
OpenconfigSystemModel = "openconfig-system"
)
var (
// ModelData is a list of supported models.
ModelData = []*pb.ModelData{{
Name: OpenconfigInterfacesModel,
Organization: "OpenConfig working group",
Version: "2.0.0",
}, {
Name: OpenconfigOpenflowModel,
Organization: "OpenConfig working group",
Version: "0.1.0",
}, {
Name: OpenconfigPlatformModel,
Organization: "OpenConfig working group",
Version: "0.5.0",
}, {
Name: OpenconfigSystemModel,
Organization: "OpenConfig working group",
Version: "0.2.0",
}}
)
......@@ -31,12 +31,12 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
log "github.com/golang/glog"
"github.com/golang/protobuf/proto"
"github.com/openconfig/gnmi/value"
"github.com/openconfig/ygot/util"
"github.com/openconfig/ygot/ygot"
"github.com/openconfig/ygot/ytypes"
log "github.com/sirupsen/logrus"
dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
pb "github.com/openconfig/gnmi/proto/gnmi"
......
......@@ -4,8 +4,8 @@ import (
"fmt"
"strconv"
log "github.com/golang/glog"
"github.com/openconfig/goyang/pkg/yang"
log "github.com/sirupsen/logrus"
pb "github.com/openconfig/gnmi/proto/gnmi"
)
......
......@@ -8,11 +8,9 @@ require (
github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a
github.com/go-openapi/runtime v0.19.22
github.com/go-openapi/strfmt v0.19.5
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.4.3
github.com/google/gnxi v0.0.0-20201221102247-c26672548161
github.com/google/uuid v1.1.2
github.com/mitchellh/go-homedir v1.1.0
github.com/neo4j/neo4j-go-driver v1.8.3
github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
github.com/openconfig/goyang v0.2.3
......
......@@ -20,7 +20,7 @@ type Core struct {
var c *Core
//Initialize does start-up housekeeping like reading controller config files
func initialize() error {
func initialize(ctx context.Context) error {
c = &Core{
database: database.Database{},
pndc: pndStore{},
......@@ -38,7 +38,7 @@ func initialize() error {
}
// TODO: Start grpc listener here
if err := httpApi(); err != nil {
if err := httpApi(ctx); err != nil {
return err
}
......@@ -62,10 +62,8 @@ func createSouthboundInterfaces() error {
}
func Run(ctx context.Context) error {
if err := initialize(); err != nil {
log.WithFields(log.Fields{
}).Error(err)
if err := initialize(ctx); err != nil {
log.WithFields(log.Fields{}).Error(err)
return err
}
log.WithFields(log.Fields{}).Info("initialisation finished")
......
......@@ -12,6 +12,13 @@ func (e *ErrNilClient) Error() string {
return fmt.Sprintf("client cannot be nil")
}
type ErrNil struct {
}
func (e *ErrNil) Error() string {
return fmt.Sprintf("struct cannot be nil")
}
type ErrNotFound struct {
id interface{}
}
......@@ -66,4 +73,4 @@ type ErrInvalidTransportOptions struct {
func (e ErrInvalidTransportOptions) Error() string {
return fmt.Sprintf("invalid transport options: %v", reflect.TypeOf(e.t))
}
\ No newline at end of file
}
......@@ -25,8 +25,8 @@ func NewGnmiTransport(opts *GnmiTransportOptions) (*Gnmi, error) {
return nil, err
}
log.WithFields(log.Fields{
"target": opts.Addr,
"tls": opts.TLS,
"target": opts.Addr,
"tls": opts.TLS,
"encoding": opts.Encoding,
}).Info("building new gNMI transport")
return &Gnmi{
......@@ -59,31 +59,35 @@ func (g *Gnmi) Get(ctx context.Context, params ...string) (interface{}, error) {
// Set takes a slice of params. This slice must contain at least one operation.
// It can contain an additional arbitrary amount of operations and extensions.
func (g *Gnmi) Set(ctx context.Context, params ...interface{}) (interface{}, error) {
func (g *Gnmi) Set(ctx context.Context, args ...interface{}) (interface{}, error) {
if g.client == nil {
return nil, &ErrNilClient{}
}
if len(params) == 0 {
if len(args) == 0 {
return nil, &ErrInvalidParameters{
f: "gnmi.Set()",
r: "no parameters provided",
}
}
// Loop over params and create ops and exts
// Invalid params cause unhealable error
// Loop over args and create ops and exts
// Invalid args cause unhealable error
ops := make([]*gnmi.Operation, 0)
exts := make([]*gnmi_ext.Extension, 0)
for _, p := range params {
for _, p := range args {
switch p.(type) {
case *gnmi.Operation:
ops = append(ops, p.(*gnmi.Operation))
op := p.(*gnmi.Operation)
if op.Target == "" {
op.Target = g.Options.Addr
}
ops = append(ops, op)
case *gnmi_ext.Extension:
exts = append(exts, p.(*gnmi_ext.Extension))
default:
return nil, &ErrInvalidParameters{
f: "gnmi.Set()",
r: "params contain invalid type",
r: "args contain invalid type",
}
}
}
......@@ -171,6 +175,9 @@ func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interf
// getWithRequest takes a fully formed GetRequest, performs the Get,
// and returns any response.
func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interface{}, error) {
if req == nil {
return nil, &ErrNil{}
}
log.WithFields(log.Fields{
"target": g.Options.Addr,
"path": req.Path,
......@@ -190,15 +197,15 @@ func (g *Gnmi) set(ctx context.Context, setOps []*gnmi.Operation,
targets := make([]string, len(setOps))
paths := make([][]string, len(setOps))
values := make([]string, len(setOps))
for i,v := range setOps {
for i, v := range setOps {
targets[i] = v.Target
paths[i] = v.Path
values[i] = v.Val
}
log.WithFields(log.Fields{
"targets": targets,
"paths": paths,
"values": values,
"paths": paths,
"values": values,
}).Info("sending gNMI set request")
return gnmi.Set(ctx, g.client, setOps, exts...)
}
......@@ -209,9 +216,9 @@ func (g *Gnmi) subscribe(ctx context.Context) error {
opts := ctx.Value("opts").(*gnmi.SubscribeOptions)
go func() {
log.WithFields(log.Fields{
"address": opts.Target,
"paths": opts.Paths,
"mode": opts.Mode,
"address": opts.Target,
"paths": opts.Paths,
"mode": opts.Mode,
"interval": opts.SampleInterval,
}).Info("subscribed to gNMI target")
for {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment