-
Notifications
You must be signed in to change notification settings - Fork 8
/
ipsec.go
170 lines (148 loc) · 6.91 KB
/
ipsec.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package collector
import (
"encoding/xml"
"fmt"
"strings"
"github.com/Juniper/go-netconf/netconf"
"github.com/prometheus/client_golang/prometheus"
)
var (
ipsecSubsystem = "ipsec"
totalIpsecErrors = 0.0
ipsecLabels = map[string][]string{"TunnelInformation": []string{"saremotegateway", "satunnelindex"}}
ipsecDesc = map[string]*prometheus.Desc{
"TunnelStatusUp": colPromDesc(ipsecSubsystem, "tunnel_status_up", "Tunnel Status (1 UP, 0 DOWN)", ipsecLabels["TunnelInformation"]),
}
)
// EnvCollector collects environment metrics, implemented as per the Collector interface.
type IpsecCollector struct{}
// NewEnvCollector returns a new EnvCollector.
func NewIpsecCollector() *IpsecCollector {
return &IpsecCollector{}
}
// Name of the collector.
func (*IpsecCollector) Name() string {
return ipsecSubsystem
}
// Get metrics and send to the Prometheus.Metric channel.
func (c *IpsecCollector) Get(ch chan<- prometheus.Metric, conf Config) ([]error, float64) {
errors := []error{}
s, err := netconf.DialSSH(conf.SSHTarget, conf.SSHClientConfig)
if err != nil {
totalIpsecErrors++
errors = append(errors, fmt.Errorf("could not connect to %q: %s", conf.SSHTarget, err))
return errors, totalIpsecErrors
}
defer s.Close()
// IPsec inactive tunnels
reply, err := s.Exec(netconf.RawMethod(`<get-inactive-tunnels/>`))
if err != nil {
totalIpsecErrors++
errors = append(errors, fmt.Errorf("could not execute netconf RPC call: %s", err))
return errors, totalIpsecErrors
}
if err := processIpsecInactiveNetconfReply(reply, ch, conf.SSHTarget); err != nil {
totalIpsecErrors++
errors = append(errors, err)
}
// IPsec active tunnels
reply, err = s.Exec(netconf.RawMethod(`<get-security-associations-information/>`))
if err != nil {
totalIpsecErrors++
errors = append(errors, fmt.Errorf("could not execute netconf RPC call: %s", err))
return errors, totalIpsecErrors
}
if err := processIpsecActiveNetconfReply(reply, ch); err != nil {
totalIpsecErrors++
errors = append(errors, err)
}
return errors, totalIpsecErrors
}
func processIpsecInactiveNetconfReply(reply *netconf.RPCReply, ch chan<- prometheus.Metric, sshTarget string) error {
var netconfInactiveTunnelReply InactiveTunnelReply
if err := xml.Unmarshal([]byte(reply.RawReply), &netconfInactiveTunnelReply); err != nil {
return fmt.Errorf("could not unmarshal netconf inactive tunnel reply xml: %s", err)
}
// Send tunnel status of inactive tunnels to Prometheus channel.
// Set tunnel_status_up to 0
for _, ipsecData := range netconfInactiveTunnelReply.IpsecUnestablishedTunnelInformation.IpsecSecurityAssociationsBlock {
saRemoteGateway := strings.Trim(ipsecData.IpsecSecurityAssociations.SaRemoteGateway, "\n")
saTunnelIndex := strings.Trim(ipsecData.IpsecSecurityAssociations.SaTunnelIndex, "\n")
ch <- prometheus.MustNewConstMetric(ipsecDesc["TunnelStatusUp"], prometheus.GaugeValue, 0, saRemoteGateway, saTunnelIndex)
}
return nil
}
// Process active ipsec SAs.
func processIpsecActiveNetconfReply(reply *netconf.RPCReply, ch chan<- prometheus.Metric) error {
var netconfActiveTunnelReply ActiveTunnelReply
if err := xml.Unmarshal([]byte(reply.RawReply), &netconfActiveTunnelReply); err != nil {
return fmt.Errorf("could not unmarshal netconf active tunnel reply xml: %s", err)
}
// Send tunnel status of active tunnels to Prometheus channel.
// Set tunnel_status_up to 1
for _, ipsecData := range netconfActiveTunnelReply.IpsecSecurityAssociationsInformation.IpsecSecurityAssociationsBlock {
saRemoteGateway := strings.Trim(ipsecData.IpsecSecurityAssociations.SaRemoteGateway, "\n")
saTunnelIndex := strings.Trim(ipsecData.IpsecSecurityAssociations.SaTunnelIndex, "\n")
ch <- prometheus.MustNewConstMetric(ipsecDesc["TunnelStatusUp"], prometheus.GaugeValue, 1, saRemoteGateway, saTunnelIndex)
}
return nil
}
type InactiveTunnelReply struct {
XMLName xml.Name `xml:"rpc-reply"`
Text string `xml:",chardata"`
Junos string `xml:"junos,attr"`
MessageID string `xml:"message-id,attr"`
Xmlns string `xml:"xmlns,attr"`
IpsecUnestablishedTunnelInformation struct {
Text string `xml:",chardata"`
Style string `xml:"style,attr"`
TotalInactiveTunnels string `xml:"total-inactive-tunnels"`
TotalInactiveTunnelsWithEstablishImmediately string `xml:"total-inactive-tunnels-with-establish-immediately"`
IpsecSecurityAssociationsBlock []struct {
Text string `xml:",chardata"`
IpsecSecurityAssociations struct {
Text string `xml:",chardata"`
SaTunnelIndex string `xml:"sa-tunnel-index"`
SaRemoteGateway string `xml:"sa-remote-gateway"`
SaPort string `xml:"sa-port"`
SaTunnelEventTime string `xml:"sa-tunnel-event-time"`
SaTunnelEvent string `xml:"sa-tunnel-event"`
SaTunnelEventNumTimes string `xml:"sa-tunnel-event-num-times"`
} `xml:"ipsec-security-associations"`
} `xml:"ipsec-security-associations-block"`
} `xml:"ipsec-unestablished-tunnel-information"`
}
type ActiveTunnelReply struct {
XMLName xml.Name `xml:"rpc-reply"`
Text string `xml:",chardata"`
Junos string `xml:"junos,attr"`
IpsecSecurityAssociationsInformation struct {
Text string `xml:",chardata"`
Style string `xml:"style,attr"`
TotalActiveTunnels string `xml:"total-active-tunnels"`
IpsecSecurityAssociationsBlock []struct {
Text string `xml:",chardata"`
SaBlockState string `xml:"sa-block-state"`
IpsecSecurityAssociations struct {
Text string `xml:",chardata"`
SaDirection string `xml:"sa-direction"`
SaTunnelIndex string `xml:"sa-tunnel-index"`
SaSpi string `xml:"sa-spi"`
SaAuxSpi string `xml:"sa-aux-spi"`
SaRemoteGateway string `xml:"sa-remote-gateway"`
SaPort string `xml:"sa-port"`
SaVpnMonitoringState string `xml:"sa-vpn-monitoring-state"`
SaProtocol string `xml:"sa-protocol"`
SaEspEncryptionAlgorithm string `xml:"sa-esp-encryption-algorithm"`
SaHmacAlgorithm string `xml:"sa-hmac-algorithm"`
SaHardLifetime string `xml:"sa-hard-lifetime"`
SaLifesizeRemaining string `xml:"sa-lifesize-remaining"`
SaVirtualSystem string `xml:"sa-virtual-system"`
} `xml:"ipsec-security-associations"`
} `xml:"ipsec-security-associations-block"`
} `xml:"ipsec-security-associations-information"`
Cli struct {
Text string `xml:",chardata"`
Banner string `xml:"banner"`
} `xml:"cli"`
}