1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
package collector
import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
vtyshEnable = kingpin.Flag("frr.vtysh", "Use vtysh to query FRR instead of each daemon's Unix socket (default: disabled, recommended: disabled).").Default("false").Bool()
vtyshPath = kingpin.Flag("frr.vtysh.path", "Path of vtysh.").Default("/usr/bin/vtysh").String()
vtyshTimeout = kingpin.Flag("frr.vtysh.timeout", "The timeout when running vtysh commands (default: 20s).").Default("20s").Duration()
vtyshSudo = kingpin.Flag("frr.vtysh.sudo", "Enable sudo when executing vtysh commands.").Bool()
frrVTYSHOptions = kingpin.Flag("frr.vtysh.options", "Additional options passed to vtysh.").Default("").String()
)
func executeBFDCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecBFDCmd(cmd)
}
func executeBGPCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecBGPCmd(cmd)
}
func executeOSPFMultiInstanceCommand(cmd string, instanceID int) ([]byte, error) {
return socketConn.ExecOSPFMultiInstanceCmd(cmd, instanceID)
}
func executeOSPFCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecOSPFCmd(cmd)
}
func executePIMCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecPIMCmd(cmd)
}
func executeZebraCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecZebraCmd(cmd)
}
func executeVRRPCommand(cmd string) ([]byte, error) {
if *vtyshEnable {
return execVtyshCommand(cmd)
}
return socketConn.ExecVRRPCmd(cmd)
}
func execVtyshCommand(vtyshCmd string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), *vtyshTimeout)
defer cancel()
var a []string
var executable string
if *vtyshSudo {
a = []string{*vtyshPath}
executable = "/usr/bin/sudo"
} else {
a = []string{}
executable = *vtyshPath
}
if *frrVTYSHOptions != "" {
frrOptions := strings.Split(*frrVTYSHOptions, " ")
a = append(a, frrOptions...)
}
a = append(a, "-c", vtyshCmd)
cmd := exec.CommandContext(ctx, executable, a...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return stdout.Bytes(), fmt.Errorf("command %s failed: %w: stderr: %s: stdout: %s", cmd, err, strings.ReplaceAll(stderr.String(), "\n", " "), strings.ReplaceAll(stdout.String(), "\n", " "))
}
return stdout.Bytes(), nil
}
|