update troubleshoot CLI, update flags and upstreams output (#16211)

* update troubleshoot CLI, update flags and upstreams output

* update troubleshoot upstreams output
This commit is contained in:
malizz 2023-02-08 16:05:22 -08:00 committed by GitHub
parent 9718079a49
commit 834ef73e8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 23 deletions

View File

@ -24,20 +24,22 @@ type cmd struct {
help string help string
// flags // flags
upstream string upstreamEnvoyID string
adminBind string upstreamIP string
envoyAdminEndpoint string
} }
func (c *cmd) init() { func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError) c.flags = flag.NewFlagSet("", flag.ContinueOnError)
c.flags.StringVar(&c.upstream, "upstream", os.Getenv("TROUBLESHOOT_UPSTREAM"), "The upstream service that receives the communication. ") c.flags.StringVar(&c.upstreamEnvoyID, "upstream-envoy-id", os.Getenv("UPSTREAM_ENVOY_ID"), "The envoy identifier of the upstream service that receives the communication. (explicit upstreams only)")
c.flags.StringVar(&c.upstreamIP, "upstream-ip", os.Getenv("UPSTREAM_IP"), "The IP address of the upstream service that receives the communication. (transparent proxy only) ")
defaultAdminBind := "localhost:19000" defaultEnvoyAdminEndpoint := "localhost:19000"
if adminBind := os.Getenv("ADMIN_BIND"); adminBind != "" { if envoyAdminEndpoint := os.Getenv("ENVOY_ADMIN_ENDPOINT"); envoyAdminEndpoint != "" {
defaultAdminBind = adminBind defaultEnvoyAdminEndpoint = envoyAdminEndpoint
} }
c.flags.StringVar(&c.adminBind, "admin-bind", defaultAdminBind, "The address:port that envoy's admin endpoint is on.") c.flags.StringVar(&c.envoyAdminEndpoint, "envoy-admin-endpoint", defaultEnvoyAdminEndpoint, "The address:port that envoy's admin endpoint is on.")
c.http = &flags.HTTPFlags{} c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags()) flags.Merge(c.flags, c.http.ClientFlags())
@ -52,12 +54,13 @@ func (c *cmd) Run(args []string) int {
return 1 return 1
} }
if c.upstream == "" { if c.upstreamEnvoyID == "" && c.upstreamIP == "" {
c.UI.Error("-upstream envoy identifier is required") c.UI.Error("-upstream-envoy-id OR -upstream-ip is required.")
c.UI.Error("Please run `consul troubleshoot upstreams` to find the corresponding upstream.")
return 1 return 1
} }
adminAddr, adminPort, err := net.SplitHostPort(c.adminBind) adminAddr, adminPort, err := net.SplitHostPort(c.envoyAdminEndpoint)
if err != nil { if err != nil {
c.UI.Error("Invalid Envoy Admin endpoint: " + err.Error()) c.UI.Error("Invalid Envoy Admin endpoint: " + err.Error())
return 1 return 1
@ -67,7 +70,8 @@ func (c *cmd) Run(args []string) int {
// localhost here. // localhost here.
adminBindIP, err := net.ResolveIPAddr("ip", adminAddr) adminBindIP, err := net.ResolveIPAddr("ip", adminAddr)
if err != nil { if err != nil {
c.UI.Error("Failed to resolve admin bind address: " + err.Error()) c.UI.Error("Failed to resolve Envoy admin endpoint: " + err.Error())
c.UI.Error("Please make sure Envoy's Admin API is enabled.")
return 1 return 1
} }
@ -76,7 +80,7 @@ func (c *cmd) Run(args []string) int {
c.UI.Error("error generating troubleshoot client: " + err.Error()) c.UI.Error("error generating troubleshoot client: " + err.Error())
return 1 return 1
} }
messages, err := t.RunAllTests(c.upstream) messages, err := t.RunAllTests(c.upstreamEnvoyID, c.upstreamIP)
if err != nil { if err != nil {
c.UI.Error("error running the tests: " + err.Error()) c.UI.Error("error running the tests: " + err.Error())
return 1 return 1
@ -111,9 +115,12 @@ Usage: consul troubleshoot proxy [options]
Connects to local envoy proxy and troubleshoots service mesh communication issues. Connects to local envoy proxy and troubleshoots service mesh communication issues.
Requires an upstream service envoy identifier. Requires an upstream service envoy identifier.
Examples: Examples:
$ consul troubleshoot proxy -upstream foo (explicit upstreams only)
$ consul troubleshoot proxy -upstream-envoy-id foo
(transparent proxy only)
$ consul troubleshoot proxy -upstream-ip <IP>
where 'foo' is the upstream envoy ID which where 'foo' is the upstream envoy identifier which
can be obtained by running: can be obtained by running:
$ consul troubleshoot upstreams [options] $ consul troubleshoot upstreams [options]
` `

View File

@ -24,17 +24,17 @@ type cmd struct {
help string help string
// flags // flags
adminBind string envoyAdminEndpoint string
} }
func (c *cmd) init() { func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError) c.flags = flag.NewFlagSet("", flag.ContinueOnError)
defaultAdminBind := "localhost:19000" defaultEnvoyAdminEndpoint := "localhost:19000"
if adminBind := os.Getenv("ADMIN_BIND"); adminBind != "" { if envoyAdminEndpoint := os.Getenv("ENVOY_ADMIN_ENDPOINT"); envoyAdminEndpoint != "" {
defaultAdminBind = adminBind defaultEnvoyAdminEndpoint = envoyAdminEndpoint
} }
c.flags.StringVar(&c.adminBind, "admin-bind", defaultAdminBind, "The address:port that envoy's admin endpoint is on.") c.flags.StringVar(&c.envoyAdminEndpoint, "envoy-admin-endpoint", defaultEnvoyAdminEndpoint, "The address:port that envoy's admin endpoint is on.")
c.http = &flags.HTTPFlags{} c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags()) flags.Merge(c.flags, c.http.ClientFlags())
@ -49,7 +49,7 @@ func (c *cmd) Run(args []string) int {
return 1 return 1
} }
adminAddr, adminPort, err := net.SplitHostPort(c.adminBind) adminAddr, adminPort, err := net.SplitHostPort(c.envoyAdminEndpoint)
if err != nil { if err != nil {
c.UI.Error("Invalid Envoy Admin endpoint: " + err.Error()) c.UI.Error("Invalid Envoy Admin endpoint: " + err.Error())
return 1 return 1
@ -59,7 +59,8 @@ func (c *cmd) Run(args []string) int {
// localhost here. // localhost here.
adminBindIP, err := net.ResolveIPAddr("ip", adminAddr) adminBindIP, err := net.ResolveIPAddr("ip", adminAddr)
if err != nil { if err != nil {
c.UI.Error("Failed to resolve admin bind address: " + err.Error()) c.UI.Error("Failed to resolve envoy admin endpoint: " + err.Error())
c.UI.Error("Please make sure Envoy's Admin API is enabled.")
return 1 return 1
} }
@ -74,14 +75,22 @@ func (c *cmd) Run(args []string) int {
return 1 return 1
} }
c.UI.Output(fmt.Sprintf("==> Upstreams (explicit upstreams only) (%v)", len(envoyIDs)))
for _, u := range envoyIDs { for _, u := range envoyIDs {
c.UI.Output(u) c.UI.Output(u)
} }
c.UI.Output(fmt.Sprintf("\n==> Upstream IPs (transparent proxy only) (%v)", len(upstreamIPs)))
for _, u := range upstreamIPs { for _, u := range upstreamIPs {
c.UI.Output(fmt.Sprintf("%+v %v %+v", u.IPs, u.IsVirtual, u.ClusterNames)) c.UI.Output(fmt.Sprintf("%+v %v %+v", u.IPs, u.IsVirtual, u.ClusterNames))
} }
c.UI.Output("\nIf you don't see your upstream address or cluster for a transparent proxy upstream:")
c.UI.Output("- Check intentions: Tproxy upstreams are configured based on intentions, make sure you " +
"have configured intentions to allow traffic to your upstream.")
c.UI.Output("- You can also check that the right cluster is being dialed by running a DNS lookup " +
"for the upstream you are dialing (i.e dig backend.svc.consul). If the address you get from that is missing " +
"from the Upstream IPs your proxy may be misconfigured.")
return 0 return 0
} }

View File

@ -52,7 +52,7 @@ func NewTroubleshoot(envoyIP *net.IPAddr, envoyPort string) (*Troubleshoot, erro
}, nil }, nil
} }
func (t *Troubleshoot) RunAllTests(envoyID string) (validate.Messages, error) { func (t *Troubleshoot) RunAllTests(upstreamEnvoyID, upstreamIP string) (validate.Messages, error) {
var allTestMessages validate.Messages var allTestMessages validate.Messages
// Get all info from proxy to set up validations. // Get all info from proxy to set up validations.
@ -91,7 +91,7 @@ func (t *Troubleshoot) RunAllTests(envoyID string) (validate.Messages, error) {
// } // }
// Validate listeners, routes, clusters, endpoints. // Validate listeners, routes, clusters, endpoints.
messages = Validate(indexedResources, envoyID, "", true, t.envoyClusters) messages = Validate(indexedResources, upstreamEnvoyID, upstreamIP, true, t.envoyClusters)
allTestMessages = append(allTestMessages, messages...) allTestMessages = append(allTestMessages, messages...)
if errors := messages.Errors(); len(errors) == 0 { if errors := messages.Errors(); len(errors) == 0 {
msg := validate.Message{ msg := validate.Message{