/
host_tcpportstatus.go
120 lines (101 loc) · 2.9 KB
/
host_tcpportstatus.go
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package collect
import (
"bytes"
"encoding/json"
"fmt"
"net"
"path/filepath"
"time"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
)
type CollectHostTCPPortStatus struct {
hostCollector *troubleshootv1beta2.TCPPortStatus
BundlePath string
}
func (c *CollectHostTCPPortStatus) Title() string {
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "TCP Port Status")
}
func (c *CollectHostTCPPortStatus) IsExcluded() (bool, error) {
return isExcluded(c.hostCollector.Exclude)
}
func (c *CollectHostTCPPortStatus) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
dialAddress := ""
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.hostCollector.Port)
if c.hostCollector.Interface != "" {
iface, err := net.InterfaceByName(c.hostCollector.Interface)
if err != nil {
return nil, errors.Wrapf(err, "lookup interface %s", c.hostCollector.Interface)
}
ip, err := getIPv4FromInterface(iface)
if err != nil {
return nil, errors.Wrapf(err, "get ipv4 address for interface %s", c.hostCollector.Interface)
}
listenAddress = fmt.Sprintf("%s:%d", ip, c.hostCollector.Port)
dialAddress = listenAddress
}
if dialAddress == "" {
ip, err := getLocalIPv4()
if err != nil {
return nil, err
}
dialAddress = fmt.Sprintf("%s:%d", ip, c.hostCollector.Port)
}
networkStatus, err := checkTCPConnection(progressChan, listenAddress, dialAddress, 10*time.Second)
if err != nil {
return nil, err
}
result := NetworkStatusResult{
Status: networkStatus,
}
b, err := json.Marshal(result)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal result")
}
collectorName := c.hostCollector.CollectorName
if collectorName == "" {
collectorName = "tcpPortStatus"
}
name := filepath.Join("host-collectors/tcpPortStatus", collectorName+".json")
output := NewResult()
output.SaveResult(c.BundlePath, name, bytes.NewBuffer(b))
return map[string][]byte{
name: b,
}, nil
}
func getIPv4FromInterface(iface *net.Interface) (net.IP, error) {
addrs, err := iface.Addrs()
if err != nil {
return nil, errors.Wrap(err, "list interface addresses")
}
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
return nil, errors.Wrapf(err, "parse interface address %q", addr.String())
}
ip = ip.To4()
if ip != nil {
return ip, nil
}
}
return nil, errors.New("interface does not have an ipv4 address")
}
func getLocalIPv4() (net.IP, error) {
interfaces, err := net.Interfaces()
if err != nil {
return nil, errors.Wrap(err, "list host network interfaces")
}
for _, iface := range interfaces {
if iface.Flags&net.FlagUp == 0 {
continue
}
if iface.Flags&net.FlagLoopback != 0 {
continue
}
ip, _ := getIPv4FromInterface(&iface)
if ip != nil {
return ip, nil
}
}
return nil, errors.New("No network interface has an IPv4 address")
}