Skip to content

Commit eb0939b

Browse files
committed
server-info command
1 parent a109291 commit eb0939b

11 files changed

Lines changed: 213 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ The changelog for Bonvoy
22

33
## Pending Release
44

5+
* Add `server-info` command to display information about the Envoy sidecar
56
* Add `log-level` command to set Envoy's log level
67
* Restructure for better memory usage and a more closed API
78

commands/certificates.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ func (g *ExpiredCertificatesCommand) Run() error {
3737
name = g.fs.Arg(0)
3838
}
3939

40-
e := envoy.NewFromServiceName(name)
40+
e, err := envoy.NewFromServiceName(name)
41+
if err != nil {
42+
return err
43+
}
4144
data := e.Certificates().Get()
4245

4346
for _, certs := range data.Certificates {

commands/listeners.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ func (g *ListenersCommand) Run() error {
3535
name = g.fs.Arg(0)
3636
}
3737

38-
e := envoy.NewFromServiceName(name)
38+
e, err := envoy.NewFromServiceName(name)
39+
if err != nil {
40+
return err
41+
}
3942
listeners := e.Listeners().Get()
4043

4144
fmt.Println("LISTENERS:")

commands/logging.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ func (g *SetLogLevelCommand) Run() error {
4444
}
4545
}
4646

47-
e := envoy.NewFromServiceName(name)
47+
e, err := envoy.NewFromServiceName(name)
48+
if err != nil {
49+
return err
50+
}
4851
e.Logging().SetLevel(level)
4952
return nil
5053
}

commands/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ func All() []Runner {
1212
BuildVersion(),
1313
BuildExpiredCertificatesCommand(),
1414
BuildSetLogLevelCommand(),
15+
BuildServerInfoCommand(),
1516
}
1617
}

commands/server_info.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package commands
2+
3+
import (
4+
"bonvoy/envoy"
5+
"flag"
6+
"fmt"
7+
"github.com/olekukonko/tablewriter"
8+
"os"
9+
)
10+
11+
type ServerInfoCommand struct {
12+
fs *flag.FlagSet
13+
name string
14+
}
15+
16+
// ListenersCommand
17+
func BuildServerInfoCommand() *ServerInfoCommand {
18+
gc := &ServerInfoCommand{
19+
fs: flag.NewFlagSet("server-info", flag.ContinueOnError),
20+
}
21+
gc.fs.StringVar(&gc.name, "service", "", "name of the service sidecar to see server information for")
22+
return gc
23+
}
24+
25+
func (g *ServerInfoCommand) Name() string {
26+
return g.fs.Name()
27+
}
28+
29+
func (g *ServerInfoCommand) Init(args []string) error {
30+
return g.fs.Parse(args)
31+
}
32+
33+
func (g *ServerInfoCommand) Run() error {
34+
var name = g.name
35+
if name == "" {
36+
name = g.fs.Arg(0)
37+
}
38+
e, err := envoy.NewFromServiceName(name)
39+
if err != nil {
40+
return err
41+
}
42+
response := e.Server().Info()
43+
g.DisplayOutput(response)
44+
return nil
45+
}
46+
47+
func (g *ServerInfoCommand) DisplayOutput(data envoy.ServerInfoJson) {
48+
fmt.Println("----------------------")
49+
fmt.Println("- Server Information -")
50+
fmt.Println("----------------------")
51+
d := [][]string{
52+
{"Version", data.Version},
53+
{"Hot Restart Version", data.HotRestartVersion},
54+
{"State", data.State},
55+
{"Uptime", data.UptimeCurrentEpoch},
56+
}
57+
table := tablewriter.NewWriter(os.Stdout)
58+
table.SetBorder(false)
59+
table.SetTablePadding("\t")
60+
table.AppendBulk(d)
61+
table.SetAlignment(tablewriter.ALIGN_LEFT)
62+
table.Render()
63+
64+
fmt.Println("")
65+
fmt.Println("--------------------")
66+
fmt.Println("- Node Information -")
67+
fmt.Println("--------------------")
68+
d = [][]string{
69+
{"Node ID", data.Node.ID},
70+
{"Node Cluster", data.Node.Cluster},
71+
{"User Agent", data.Node.UserAgentName},
72+
{"Envoy Version", data.Node.Metadata.EnvoyVersion},
73+
{"Namespace", data.Node.Metadata.Namespace},
74+
}
75+
table = tablewriter.NewWriter(os.Stdout)
76+
table.SetBorder(false)
77+
table.SetTablePadding("\t")
78+
table.AppendBulk(d)
79+
table.SetAlignment(tablewriter.ALIGN_LEFT)
80+
table.Render()
81+
82+
fmt.Println("")
83+
fmt.Println("------------------------")
84+
fmt.Println("- Command Line Options -")
85+
fmt.Println("------------------------")
86+
d = [][]string{
87+
{"Concurrency", fmt.Sprintf("%d", data.ServerCommandLineOptions.Concurrency)},
88+
{"Mode", data.ServerCommandLineOptions.Mode},
89+
{"Log Level", data.ServerCommandLineOptions.LogLevel},
90+
{"Component Log Level", data.ServerCommandLineOptions.ComponentLogLevel},
91+
{"Log Format", data.ServerCommandLineOptions.LogFormat},
92+
{"Drain Strategy", data.ServerCommandLineOptions.DrainStrategy},
93+
{"Drain Time", data.ServerCommandLineOptions.DrainTime},
94+
{"Config Path", data.ServerCommandLineOptions.ConfigPath},
95+
{"Parent Shutdown Time", data.ServerCommandLineOptions.ParentShutdownTime},
96+
}
97+
table = tablewriter.NewWriter(os.Stdout)
98+
table.SetBorder(false)
99+
table.SetTablePadding("\t")
100+
table.AppendBulk(d)
101+
table.SetAlignment(tablewriter.ALIGN_LEFT)
102+
table.Render()
103+
}

docker/client.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func NewClient() Client {
2424
}
2525
}
2626

27-
func (c *Client) GetEnvoyPid(name string) int {
27+
func (c *Client) GetEnvoyPid(name string) (int, error) {
2828
filter := filters.NewArgs()
2929
filter.Add("name", "connect-proxy-" + name)
3030

@@ -33,7 +33,7 @@ func (c *Client) GetEnvoyPid(name string) int {
3333
Filters: filter,
3434
})
3535
if err != nil {
36-
panic(err)
36+
return 0, err
3737
}
3838
var containerNames []string
3939
for _, container := range containers {
@@ -43,8 +43,10 @@ func (c *Client) GetEnvoyPid(name string) int {
4343
desiredName := ""
4444
if len(containerNames) > 1 {
4545
desiredName = c.SelectDesiredContainer(containerNames)
46-
} else {
46+
} else if len(containerNames) == 1 {
4747
desiredName = containerNames[0]
48+
} else {
49+
return 0, fmt.Errorf("No sidecar found for name: " + name)
4850
}
4951

5052
fmt.Printf("Entering %s\n\n", strings.TrimLeft(desiredName, "/"))
@@ -57,10 +59,9 @@ func (c *Client) GetEnvoyPid(name string) int {
5759
}
5860
container, err := c.cli.ContainerInspect(context.Background(), desiredId)
5961
if err != nil {
60-
fmt.Printf("Failed to inspect container %v\n", err)
61-
panic(err)
62+
return 0, err
6263
}
63-
return container.State.Pid
64+
return container.State.Pid, nil
6465
}
6566

6667
func (c *Client) SelectDesiredContainer(names []string) string {

envoy/instance.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ func GetDefaultHost() string {
1717
return viper.GetString("ENVOY_HOST")
1818
}
1919

20-
func NewFromServiceName(name string) Instance {
20+
func NewFromServiceName(name string) (Instance, error) {
2121
dci := docker.NewClient()
22-
pid := dci.GetEnvoyPid(name)
23-
return Instance{
24-
Address: GetDefaultHost(),
25-
Pid: pid,
26-
docker: dci,
27-
nsenter: nsenter.NewClient(pid),
22+
pid, err := dci.GetEnvoyPid(name)
23+
if err != nil {
24+
return Instance{}, err
25+
} else {
26+
return Instance{
27+
Address: GetDefaultHost(),
28+
Pid: pid,
29+
docker: dci,
30+
nsenter: nsenter.NewClient(pid),
31+
}, nil
2832
}
2933
}

envoy/server.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package envoy
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"strings"
7+
)
8+
9+
type Server struct {
10+
i *Instance
11+
endpoints ServerEndpoints
12+
}
13+
14+
type ServerEndpoints struct {
15+
info string
16+
}
17+
func (i *Instance) Server() *Server {
18+
return &Server{
19+
i: i,
20+
endpoints: ServerEndpoints{
21+
info: i.Address + "/server_info",
22+
},
23+
}
24+
}
25+
26+
func (l *Server) Info() ServerInfoJson {
27+
rawJson := l.i.nsenter.Curl("-s", l.endpoints.info)
28+
jsonData := []byte(strings.Trim(rawJson, " "))
29+
30+
var response ServerInfoJson
31+
err := json.Unmarshal(jsonData, &response)
32+
if err != nil {
33+
fmt.Println(err)
34+
panic(err)
35+
}
36+
return response
37+
}
38+
39+
type ServerInfoJson struct {
40+
Version string `json:"version"`
41+
State string `json:"state"`
42+
HotRestartVersion string `json:"hot_restart_version"`
43+
ServerCommandLineOptions ServerCommandLineOptionsJson `json:"command_line_options"`
44+
Node ServerNode `json:"node"`
45+
UptimeCurrentEpoch string `json:"uptime_current_epoch"`
46+
UptimeAllEpochs string `json:"uptime_all_epochs"`
47+
}
48+
49+
type ServerCommandLineOptionsJson struct {
50+
Concurrency int `json:"concurrency"`
51+
ConfigPath string `json:"config_path"`
52+
LogLevel string `json:"log_level"`
53+
ComponentLogLevel string `json:"component_log_level"`
54+
LogFormat string `json:"log_format"`
55+
LogFormatEscaped bool `json:"log_format_escaped"`
56+
Mode string `json:"mode"`
57+
DrainStrategy string `json:"drain_strategy"`
58+
DrainTime string `json:"drain_time"`
59+
ParentShutdownTime string `json:"parent_shutdown_time"`
60+
}
61+
62+
type ServerNode struct {
63+
ID string `json:"id"`
64+
Cluster string `json:"cluster"`
65+
Metadata ServerMetadata `json:"metadata"`
66+
UserAgentName string `json:"user_agent_name"`
67+
}
68+
69+
type ServerMetadata struct {
70+
Namespace string `json:"namespace"`
71+
EnvoyVersion string `json:"envoy_version"`
72+
}

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ require (
1414
github.com/mattn/go-isatty v0.0.13 // indirect
1515
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
1616
github.com/morikuni/aec v1.0.0 // indirect
17+
github.com/olekukonko/tablewriter v0.0.5 // indirect
1718
github.com/rakyll/gotest v0.0.6 // indirect
1819
github.com/sirupsen/logrus v1.8.1 // indirect
1920
github.com/spf13/viper v1.7.1
21+
github.com/stretchr/testify v1.6.1
2022
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
2123
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
2224
google.golang.org/grpc v1.38.0 // indirect
23-
github.com/stretchr/testify v1.6.1
2425
)

0 commit comments

Comments
 (0)