狠狠撸

狠狠撸Share a Scribd company logo
?
2
3
4
5
6
7
const (
QUAGGAD_MODULE = "quaggad"
QUAGGAD_PORT = 2699
)
func grpcRegisterModule(conn *grpc.ClientConn) error {
client := rpc.NewRegisterClient(conn)
request := &rpc.RegisterModuleRequest{
Module: QUAGGAD_MODULE,
Port: fmt.Sprintf("%d", QUAGGAD_PORT),
}
_, err := client.DoRegisterModule(context.Background(), request)
if err != nil {
return err
}
return nil
}
8
var showCmdMap = map[string]func(string) *string{
"quagga_show": quaggaShow,
}
func quaggaShow(line string) *string {
return quaggaVtysh(line)
}
func grpcRegisterCommands(conn *grpc.ClientConn) {
client := rpc.NewRegisterClient(conn)
var showCommands []rpc.RegisterRequest
json.Unmarshal([]byte(showCmdSpec), &showCommands)
showParser = cmd.NewParser()
for _, command := range showCommands {
command.Module = QUAGGAD_MODULE
command.Privilege = 1
command.Code = rpc.ExecCode_REDIRECT_SHOW
_, err := client.DoRegister(context.Background(), &command)
if err != nil {
grpclog.Fatalf("client DoRegister failed: %v", err)
}
showParser.InstallLine(command.Line, showCmdMap[command.Name])
}
const showCmdSpec = `
[
{
"name": "quagga_show",
"line": "show running-config",
"mode": "exec",
"helps": [
"Show running system information",
"running configuration"
]
},
{
...
9
func (s *grpcShowServer) Show(request *rpc.ShowRequest, stream rpc.Show_ShowServer)
error {
reply := &rpc.ShowReply{}
_, fn, _, _ := showParser.ParseLine(request.Line)
show := fn.(func(string) *string)
out := show(request.Line)
lines := strings.Split(*out, "n")
for _, line := range lines {
reply.Str = fmt.Sprintln(line)
err := stream.Send(reply)
if err != nil {
fmt.Println(err)
break
}
}
return nil
}
10
11
12
func grpcSubscribe(conn *grpc.ClientConn) (rpc.Config_DoConfigClient, error) {
client := rpc.NewConfigClient(conn)
stream, err := client.DoConfig(context.Background())
if err != nil {
return nil, err
}
path := []string{"interfaces", "protocols", "policy"}
request := &rpc.ConfigRequest{
Type: rpc.ConfigType_SUBSCRIBE_MULTI,
Module: QUAGGAD_MODULE,
Port: QUAGGAD_PORT,
Path: path,
}
err = stream.Send(request)
if err != nil {
return nil, err
}
return stream, err
}
13
func grpcLoop() {
...
for {
conf, err := stream.Recv()
...
switch conf.Type {
case rpc.ConfigType_VALIDATE_START:
validating = true
quaggaConfigStateSync()
case rpc.ConfigType_VALIDATE_END:
request := &rpc.ConfigRequest{}
if quaggaConfigValid(f) {
request.Type = rpc.ConfigType_VALIDATE_SUCCESS
} else {
request.Type = rpc.ConfigType_VALIDATE_FAILED
}
err := stream.Send(request)
validating = false
case rpc.ConfigType_COMMIT_START:
case rpc.ConfigType_COMMIT_END:
case rpc.ConfigType_SET, rpc.ConfigType_DELETE:
quaggaConfig(int(conf.Type), conf.Path)
default:
}
}
14
func quaggaInterfacesInterfaceIpv4OspfAuthenticationMd5KeyId(Cmd int, Args cmd.Args) int {
//interfaces interface WORD ipv4 ospf authentication md5 key-id WORD
switch Cmd {
case cmd.Set:
case cmd.Delete:
}
return cmd.Success
}
func initConfig() {
configParser = cmd.NewParser()
configParser.InstallCmd(
[]string{"interfaces", "interface", "WORD", "ipv4", "ospf", "authentication",
quaggaInterfacesInterfaceIpv4OspfAuthenticationMd5KeyId)
...
func quaggaConfig(command int, path []string) {
switch command {
case cmd.Set:
fmt.Println("[cmd] add", path)
case cmd.Delete:
fmt.Println("[cmd] del", path)
}
if !validating {
ret, fn, args, _ := configParser.ParseCmd(path)
if ret == cmd.ParseSuccess {
fn.(func(int, cmd.Args) int)(command, args)
}
}
quaggaConfigStateUpdate(command, path)
}

More Related Content

openconfigd

  • 1. ?
  • 2. 2
  • 3. 3
  • 4. 4
  • 5. 5
  • 6. 6
  • 7. 7 const ( QUAGGAD_MODULE = "quaggad" QUAGGAD_PORT = 2699 ) func grpcRegisterModule(conn *grpc.ClientConn) error { client := rpc.NewRegisterClient(conn) request := &rpc.RegisterModuleRequest{ Module: QUAGGAD_MODULE, Port: fmt.Sprintf("%d", QUAGGAD_PORT), } _, err := client.DoRegisterModule(context.Background(), request) if err != nil { return err } return nil }
  • 8. 8 var showCmdMap = map[string]func(string) *string{ "quagga_show": quaggaShow, } func quaggaShow(line string) *string { return quaggaVtysh(line) } func grpcRegisterCommands(conn *grpc.ClientConn) { client := rpc.NewRegisterClient(conn) var showCommands []rpc.RegisterRequest json.Unmarshal([]byte(showCmdSpec), &showCommands) showParser = cmd.NewParser() for _, command := range showCommands { command.Module = QUAGGAD_MODULE command.Privilege = 1 command.Code = rpc.ExecCode_REDIRECT_SHOW _, err := client.DoRegister(context.Background(), &command) if err != nil { grpclog.Fatalf("client DoRegister failed: %v", err) } showParser.InstallLine(command.Line, showCmdMap[command.Name]) } const showCmdSpec = ` [ { "name": "quagga_show", "line": "show running-config", "mode": "exec", "helps": [ "Show running system information", "running configuration" ] }, { ...
  • 9. 9 func (s *grpcShowServer) Show(request *rpc.ShowRequest, stream rpc.Show_ShowServer) error { reply := &rpc.ShowReply{} _, fn, _, _ := showParser.ParseLine(request.Line) show := fn.(func(string) *string) out := show(request.Line) lines := strings.Split(*out, "n") for _, line := range lines { reply.Str = fmt.Sprintln(line) err := stream.Send(reply) if err != nil { fmt.Println(err) break } } return nil }
  • 10. 10
  • 11. 11
  • 12. 12 func grpcSubscribe(conn *grpc.ClientConn) (rpc.Config_DoConfigClient, error) { client := rpc.NewConfigClient(conn) stream, err := client.DoConfig(context.Background()) if err != nil { return nil, err } path := []string{"interfaces", "protocols", "policy"} request := &rpc.ConfigRequest{ Type: rpc.ConfigType_SUBSCRIBE_MULTI, Module: QUAGGAD_MODULE, Port: QUAGGAD_PORT, Path: path, } err = stream.Send(request) if err != nil { return nil, err } return stream, err }
  • 13. 13 func grpcLoop() { ... for { conf, err := stream.Recv() ... switch conf.Type { case rpc.ConfigType_VALIDATE_START: validating = true quaggaConfigStateSync() case rpc.ConfigType_VALIDATE_END: request := &rpc.ConfigRequest{} if quaggaConfigValid(f) { request.Type = rpc.ConfigType_VALIDATE_SUCCESS } else { request.Type = rpc.ConfigType_VALIDATE_FAILED } err := stream.Send(request) validating = false case rpc.ConfigType_COMMIT_START: case rpc.ConfigType_COMMIT_END: case rpc.ConfigType_SET, rpc.ConfigType_DELETE: quaggaConfig(int(conf.Type), conf.Path) default: } }
  • 14. 14 func quaggaInterfacesInterfaceIpv4OspfAuthenticationMd5KeyId(Cmd int, Args cmd.Args) int { //interfaces interface WORD ipv4 ospf authentication md5 key-id WORD switch Cmd { case cmd.Set: case cmd.Delete: } return cmd.Success } func initConfig() { configParser = cmd.NewParser() configParser.InstallCmd( []string{"interfaces", "interface", "WORD", "ipv4", "ospf", "authentication", quaggaInterfacesInterfaceIpv4OspfAuthenticationMd5KeyId) ... func quaggaConfig(command int, path []string) { switch command { case cmd.Set: fmt.Println("[cmd] add", path) case cmd.Delete: fmt.Println("[cmd] del", path) } if !validating { ret, fn, args, _ := configParser.ParseCmd(path) if ret == cmd.ParseSuccess { fn.(func(int, cmd.Args) int)(command, args) } } quaggaConfigStateUpdate(command, path) }