From 5e640ac49906fa76c891d4555d4f844d32402792 Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut <134911583+absolutelightning@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:27:26 +0530 Subject: [PATCH] NET-3860 - [Supportability] consul troubleshoot CLI for verifying ports (#19836) * NET-3860 * fix go mod * remove license * dummy commit to trigger ci * fix go mod * fix go mod tidy --- .changelog/18329.txt | 4 + command/registry.go | 2 + .../troubleshoot/ports/troubleshoot_ports.go | 89 +++++++++++++++++++ go.mod | 8 +- go.sum | 12 +-- troubleshoot/go.mod | 5 +- troubleshoot/go.sum | 14 +-- troubleshoot/ports/hostport.go | 6 ++ troubleshoot/ports/troubleshoot_ports.go | 50 +++++++++++ troubleshoot/ports/troubleshoot_ports_test.go | 52 +++++++++++ troubleshoot/ports/troubleshoot_protocol.go | 5 ++ troubleshoot/ports/troubleshoot_tcp.go | 21 +++++ .../content/commands/troubleshoot/index.mdx | 2 + .../content/commands/troubleshoot/ports.mdx | 47 ++++++++++ website/data/commands-nav-data.json | 4 + 15 files changed, 305 insertions(+), 16 deletions(-) create mode 100644 .changelog/18329.txt create mode 100644 command/troubleshoot/ports/troubleshoot_ports.go create mode 100644 troubleshoot/ports/hostport.go create mode 100644 troubleshoot/ports/troubleshoot_ports.go create mode 100644 troubleshoot/ports/troubleshoot_ports_test.go create mode 100644 troubleshoot/ports/troubleshoot_protocol.go create mode 100644 troubleshoot/ports/troubleshoot_tcp.go create mode 100644 website/content/commands/troubleshoot/ports.mdx diff --git a/.changelog/18329.txt b/.changelog/18329.txt new file mode 100644 index 000000000..ab3671de8 --- /dev/null +++ b/.changelog/18329.txt @@ -0,0 +1,4 @@ +```release-note:improvement +cli: Adds cli support for checking TCP connection for ports. If -ports flag is not given, it will check for +default ports of consul listed here - https://developer.hashicorp.com/consul/docs/install/ports +``` \ No newline at end of file diff --git a/command/registry.go b/command/registry.go index b370f14bc..822726dd5 100644 --- a/command/registry.go +++ b/command/registry.go @@ -123,6 +123,7 @@ import ( tlscert "github.com/hashicorp/consul/command/tls/cert" tlscertcreate "github.com/hashicorp/consul/command/tls/cert/create" "github.com/hashicorp/consul/command/troubleshoot" + troubleshootports "github.com/hashicorp/consul/command/troubleshoot/ports" troubleshootproxy "github.com/hashicorp/consul/command/troubleshoot/proxy" troubleshootupstreams "github.com/hashicorp/consul/command/troubleshoot/upstreams" "github.com/hashicorp/consul/command/validate" @@ -255,6 +256,7 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"troubleshoot", func(ui cli.Ui) (cli.Command, error) { return troubleshoot.New(), nil }}, entry{"troubleshoot proxy", func(ui cli.Ui) (cli.Command, error) { return troubleshootproxy.New(ui), nil }}, entry{"troubleshoot upstreams", func(ui cli.Ui) (cli.Command, error) { return troubleshootupstreams.New(ui), nil }}, + entry{"troubleshoot ports", func(ui cli.Ui) (cli.Command, error) { return troubleshootports.New(ui), nil }}, entry{"validate", func(ui cli.Ui) (cli.Command, error) { return validate.New(ui), nil }}, entry{"version", func(ui cli.Ui) (cli.Command, error) { return version.New(ui), nil }}, entry{"watch", func(ui cli.Ui) (cli.Command, error) { return watch.New(ui, MakeShutdownCh()), nil }}, diff --git a/command/troubleshoot/ports/troubleshoot_ports.go b/command/troubleshoot/ports/troubleshoot_ports.go new file mode 100644 index 000000000..108870305 --- /dev/null +++ b/command/troubleshoot/ports/troubleshoot_ports.go @@ -0,0 +1,89 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package ports + +import ( + "flag" + "fmt" + "github.com/hashicorp/consul/troubleshoot/ports" + "os" + + "github.com/hashicorp/consul/command/cli" + "github.com/hashicorp/consul/command/flags" +) + +func New(ui cli.Ui) *cmd { + c := &cmd{UI: ui} + c.init() + return c +} + +type cmd struct { + UI cli.Ui + flags *flag.FlagSet + help string + + // flags + host string + ports string +} + +func (c *cmd) init() { + c.flags = flag.NewFlagSet("", flag.ContinueOnError) + + c.flags.StringVar(&c.host, "host", os.Getenv("CONSUL_HTTP_ADDR"), "The consul server host") + + c.flags.StringVar(&c.ports, "ports", "", "Custom ports to troubleshoot") + + c.help = flags.Usage(help, c.flags) +} + +func (c *cmd) Run(args []string) int { + + if err := c.flags.Parse(args); err != nil { + c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err)) + return 1 + } + + if c.host == "" { + c.UI.Error("-host is required. or set environment variable CONSUL_HTTP_ADDR") + return 1 + } + + if c.ports == "" { + ports.TroubleshootDefaultPorts(c.host) + } else { + ports.TroubleShootCustomPorts(c.host, c.ports) + } + return 0 +} + +func (c *cmd) Synopsis() string { + return synopsis +} + +func (c *cmd) Help() string { + return c.help +} + +const ( + synopsis = "Prints open and closed ports on the Consul server" + help = ` +Usage: consul troubleshoot ports [options] + Checks ports for TCP connectivity. Add the -ports flag to check specific ports or omit the -ports flag to check default ports. + Refer to the following reference for default ports: https://developer.hashicorp.com/consul/docs/install/ports + + consul troubleshoot ports -host localhost + + or + export CONSUL_HTTP_ADDR=localhost + consul troubleshoot ports + + Use the -ports flag to check non-default ports, for example: + consul troubleshoot ports -host localhost -ports 1023,1024 + or + export CONSUL_HTTP_ADDR=localhost + consul troubleshoot ports -ports 1234,8500 +` +) diff --git a/go.mod b/go.mod index 7810f27a9..bed3b8381 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/hashicorp/consul/api v1.25.1 github.com/hashicorp/consul/envoyextensions v0.4.1 github.com/hashicorp/consul/proto-public v0.4.1 - github.com/hashicorp/consul/sdk v0.14.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/consul/troubleshoot v0.3.1 github.com/hashicorp/go-bexpr v0.1.2 github.com/hashicorp/go-checkpoint v0.5.0 @@ -107,7 +107,7 @@ require ( golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.7.0 - golang.org/x/sync v0.2.0 + golang.org/x/sync v0.3.0 golang.org/x/sys v0.13.0 golang.org/x/time v0.3.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e @@ -256,10 +256,10 @@ require ( go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.9.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.12.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/api v0.114.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect diff --git a/go.sum b/go.sum index 46928bc36..701a1205c 100644 --- a/go.sum +++ b/go.sum @@ -1070,8 +1070,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1158,8 +1158,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1334,8 +1334,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index f5645a50f..c58239e40 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -12,10 +12,11 @@ exclude ( ) require ( - github.com/envoyproxy/go-control-plane v0.11.1 + github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e github.com/hashicorp/consul/api v1.24.0 github.com/hashicorp/consul/envoyextensions v0.4.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/stretchr/testify v1.8.3 google.golang.org/protobuf v1.30.0 ) @@ -34,6 +35,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect @@ -41,6 +43,7 @@ require ( github.com/mattn/go-isatty v0.0.17 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.4.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect diff --git a/troubleshoot/go.sum b/troubleshoot/go.sum index ef0e795c4..648c03f62 100644 --- a/troubleshoot/go.sum +++ b/troubleshoot/go.sum @@ -80,8 +80,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e h1:g8euodkL4GdSpVAjfzhssb07KgVmOUqyF4QOmwFumTs= github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e/go.mod h1:/NGEcKqwNq3HAS2vCqHfsPx9sJZbkiNQ6dGx9gTE/NA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -161,7 +161,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= +github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU= +github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -188,6 +189,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -209,8 +211,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -250,6 +252,7 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -271,6 +274,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -586,8 +590,8 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/troubleshoot/ports/hostport.go b/troubleshoot/ports/hostport.go new file mode 100644 index 000000000..e7e949478 --- /dev/null +++ b/troubleshoot/ports/hostport.go @@ -0,0 +1,6 @@ +package ports + +type hostPort struct { + host string + port string +} diff --git a/troubleshoot/ports/troubleshoot_ports.go b/troubleshoot/ports/troubleshoot_ports.go new file mode 100644 index 000000000..d885a61cf --- /dev/null +++ b/troubleshoot/ports/troubleshoot_ports.go @@ -0,0 +1,50 @@ +package ports + +import ( + "fmt" + "strings" +) + +func TroubleshootDefaultPorts(host string) []string { + // Source - https://developer.hashicorp.com/consul/docs/install/ports + ports := []string{"8600", "8500", "8501", "8502", "8503", "8301", "8302", "8300"} + return troubleshootRun(ports, host) +} + +func TroubleShootCustomPorts(host string, ports string) []string { + portsArr := strings.Split(ports, ",") + return troubleshootRun(portsArr, host) +} + +func troubleshootRun(ports []string, host string) []string { + + resultsChannel := make(chan string) + defer close(resultsChannel) + + var counter = 0 + + for _, port := range ports { + counter += 1 + tcpTroubleShoot := troubleShootTcp{} + port := port + go func() { + err := tcpTroubleShoot.dialPort(&hostPort{host: host, port: port}) + var res string + if err != nil { + res = fmt.Sprintf("TCP: Port %s on %s is closed, unreachable, or the connection timed out.\n", port, host) + } else { + // If no error occurs, the connection was successful, and the port is open. + res = fmt.Sprintf("TCP: Port %s on %s is open.\n", port, host) + } + resultsChannel <- res + }() + } + + resultsArr := make([]string, counter) + for itr := 0; itr < counter; itr++ { + res := <-resultsChannel + fmt.Print(res) + resultsArr[itr] = res + } + return resultsArr +} diff --git a/troubleshoot/ports/troubleshoot_ports_test.go b/troubleshoot/ports/troubleshoot_ports_test.go new file mode 100644 index 000000000..abd4718ac --- /dev/null +++ b/troubleshoot/ports/troubleshoot_ports_test.go @@ -0,0 +1,52 @@ +package ports + +import ( + "fmt" + "github.com/hashicorp/consul/sdk/testutil" + "github.com/stretchr/testify/require" + "strconv" + "strings" + "testing" +) + +func TestTroubleShootCustom_Ports(t *testing.T) { + // Create a test Consul server. + srv1, err := testutil.NewTestServerConfigT(t, nil) + if err != nil { + t.Fatal(err) + } + + results := TroubleShootCustomPorts("127.0.0.1", strings.Join([]string{ + strconv.Itoa(srv1.Config.Ports.HTTP), + strconv.Itoa(srv1.Config.Ports.DNS), + strconv.Itoa(srv1.Config.Ports.HTTPS), + strconv.Itoa(srv1.Config.Ports.GRPC), + strconv.Itoa(srv1.Config.Ports.SerfLan), + strconv.Itoa(srv1.Config.Ports.SerfWan), + strconv.Itoa(srv1.Config.Ports.Server)}, ",")) + expectedResults := []string{ + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.HTTP)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.GRPC)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.HTTPS)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.SerfLan)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.SerfWan)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.DNS)), + fmt.Sprintf("TCP: Port %s on 127.0.0.1 is open.\n", strconv.Itoa(srv1.Config.Ports.Server)), + } + for _, res := range expectedResults { + require.Contains(t, results, res) + } + defer srv1.Stop() +} + +func TestTroubleShootCustom_Ports_Not_Reachable(t *testing.T) { + results := TroubleShootCustomPorts("127.0.0.1", strings.Join([]string{"8777", "8888"}, ",")) + + expectedResults := []string{ + fmt.Sprintf("TCP: Port 8777 on 127.0.0.1 is closed, unreachable, or the connection timed out.\n"), + fmt.Sprintf("TCP: Port 8888 on 127.0.0.1 is closed, unreachable, or the connection timed out.\n"), + } + for _, res := range expectedResults { + require.Contains(t, results, res) + } +} diff --git a/troubleshoot/ports/troubleshoot_protocol.go b/troubleshoot/ports/troubleshoot_protocol.go new file mode 100644 index 000000000..07a6f4e7a --- /dev/null +++ b/troubleshoot/ports/troubleshoot_protocol.go @@ -0,0 +1,5 @@ +package ports + +type troubleShootProtocol interface { + dialPort(hostPort *hostPort) error +} diff --git a/troubleshoot/ports/troubleshoot_tcp.go b/troubleshoot/ports/troubleshoot_tcp.go new file mode 100644 index 000000000..2babdb882 --- /dev/null +++ b/troubleshoot/ports/troubleshoot_tcp.go @@ -0,0 +1,21 @@ +package ports + +import ( + "net" + "time" +) + +type troubleShootTcp struct { +} + +func (tcp *troubleShootTcp) dialPort(hostPort *hostPort) error { + address := net.JoinHostPort(hostPort.host, hostPort.port) + + // Attempt to establish a TCP connection with a timeout. + conn, err := net.DialTimeout("tcp", address, 5*time.Second) + if err != nil { + return err + } + defer conn.Close() + return nil +} diff --git a/website/content/commands/troubleshoot/index.mdx b/website/content/commands/troubleshoot/index.mdx index 0c992aab1..74d9d9cec 100644 --- a/website/content/commands/troubleshoot/index.mdx +++ b/website/content/commands/troubleshoot/index.mdx @@ -22,6 +22,7 @@ Subcommands: proxy Troubleshoots service mesh issues from the current Envoy instance upstreams Gets upstream Envoy identifiers and IPs configured for the proxy + ports Prints open and closed ports on the Consul server. ``` For more information, examples, and usage about a subcommand, click on the name @@ -29,3 +30,4 @@ of the subcommand in the sidebar or one of the links below: - [proxy](/consul/commands/troubleshoot/proxy) - [upstreams](/consul/commands/troubleshoot/upstreams) +- [ports](/consul/commands/troubleshoot/ports) diff --git a/website/content/commands/troubleshoot/ports.mdx b/website/content/commands/troubleshoot/ports.mdx new file mode 100644 index 000000000..5a4d5faf5 --- /dev/null +++ b/website/content/commands/troubleshoot/ports.mdx @@ -0,0 +1,47 @@ +--- +layout: commands +page_title: 'Commands: Troubleshoot Ports' +description: >- + The `consul troubleshoot ports` Helps troubleshoot TCP ports by printing if they are open or closed. +--- + +# Consul Troubleshoot Upstreams + +Command: `consul troubleshoot ports` + +The `troubleshoot ports` prints TCP port statuses to help you troubleshoot port connectivity. + +## Usage + +Usage: `consul troubleshoot ports [options]` + +#### Command Options + +- `-host=` - Host name to troubleshoot TCP ports for. You can also set the `CONSUL_HTTP_ADDR` environment variable instead of using the `-host` flag. +- `-ports=` - Specifies a comma-separated list of custom ports to check. + +## Examples + +The following example checks the default ports Consul server uses for TCP connectivity. Note that the `CONSUL_HTTP_ADDR` environment variable is set to `localhost`. As a result, the `-host` flag is not required. +Refer to [Required Ports](/consul/docs/install/ports) for additional information. + +```shell-session +$ export CONSUL_HTTP_ADDR=localhost +$ consul troubleshoot ports +TCP: Port 8501 on localhost is open. +TCP: Port 8502 on localhost is open. +TCP: Port 8503 on localhost is open. +TCP: Port 8302 on localhost is open. +TCP: Port 8300 on localhost is open. +TCP: Port 8600 on localhost is open. +TCP: Port 8301 on localhost is open. +TCP: Port 8500 on localhost is open. +``` + +The following example checks TCP ports status on the `hashicorp.com` host. + +```shell-session +$ consul troubleshoot ports -host hashicorp.com -ports 80,8077 +TCP: Port 80 on hashicorp.com is open. +TCP: Port 8077 on hashicorp.com is closed, unreachable, or the connection timed out. +``` diff --git a/website/data/commands-nav-data.json b/website/data/commands-nav-data.json index dd38459a9..8b440b6c1 100644 --- a/website/data/commands-nav-data.json +++ b/website/data/commands-nav-data.json @@ -550,6 +550,10 @@ { "title": "proxy", "path": "troubleshoot/proxy" + }, + { + "title": "ports", + "path": "troubleshoot/ports" } ] },