TUN-8785: include the icmp sources in the diag's tunnel state

Closes TUN-8785
This commit is contained in:
Luis Neto 2024-12-10 10:42:33 -08:00
parent 29f0cf354c
commit d74ca97b51
5 changed files with 57 additions and 20 deletions

View File

@ -552,6 +552,13 @@ func StartServer(
tracker := tunnelstate.NewConnTracker(log) tracker := tunnelstate.NewConnTracker(log)
observer.RegisterSink(tracker) observer.RegisterSink(tracker)
ipv4, ipv6, err := determineICMPSources(c, log)
sources := make([]string, 0)
if err == nil {
sources = append(sources, ipv4.String())
sources = append(sources, ipv6.String())
}
readinessServer := metrics.NewReadyServer(clientID, tracker) readinessServer := metrics.NewReadyServer(clientID, tracker)
diagnosticHandler := diagnostic.NewDiagnosticHandler( diagnosticHandler := diagnostic.NewDiagnosticHandler(
log, log,
@ -562,6 +569,7 @@ func StartServer(
tracker, tracker,
c, c,
nonSecretFlagsList, nonSecretFlagsList,
sources,
) )
metricsConfig := metrics.Config{ metricsConfig := metrics.Config{
ReadyServer: readinessServer, ReadyServer: readinessServer,

View File

@ -352,20 +352,9 @@ func adjustIPVersionByBindAddress(ipVersion allregions.ConfigIPVersion, ip net.I
} }
func newICMPRouter(c *cli.Context, logger *zerolog.Logger) (ingress.ICMPRouterServer, error) { func newICMPRouter(c *cli.Context, logger *zerolog.Logger) (ingress.ICMPRouterServer, error) {
ipv4Src, err := determineICMPv4Src(c.String("icmpv4-src"), logger) ipv4Src, ipv6Src, err := determineICMPSources(c, logger)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to determine IPv4 source address for ICMP proxy") return nil, err
}
logger.Info().Msgf("ICMP proxy will use %s as source for IPv4", ipv4Src)
ipv6Src, zone, err := determineICMPv6Src(c.String("icmpv6-src"), logger, ipv4Src)
if err != nil {
return nil, errors.Wrap(err, "failed to determine IPv6 source address for ICMP proxy")
}
if zone != "" {
logger.Info().Msgf("ICMP proxy will use %s in zone %s as source for IPv6", ipv6Src, zone)
} else {
logger.Info().Msgf("ICMP proxy will use %s as source for IPv6", ipv6Src)
} }
icmpRouter, err := ingress.NewICMPRouter(ipv4Src, ipv6Src, logger, icmpFunnelTimeout) icmpRouter, err := ingress.NewICMPRouter(ipv4Src, ipv6Src, logger, icmpFunnelTimeout)
@ -375,6 +364,28 @@ func newICMPRouter(c *cli.Context, logger *zerolog.Logger) (ingress.ICMPRouterSe
return icmpRouter, nil return icmpRouter, nil
} }
func determineICMPSources(c *cli.Context, logger *zerolog.Logger) (netip.Addr, netip.Addr, error) {
ipv4Src, err := determineICMPv4Src(c.String("icmpv4-src"), logger)
if err != nil {
return netip.Addr{}, netip.Addr{}, errors.Wrap(err, "failed to determine IPv4 source address for ICMP proxy")
}
logger.Info().Msgf("ICMP proxy will use %s as source for IPv4", ipv4Src)
ipv6Src, zone, err := determineICMPv6Src(c.String("icmpv6-src"), logger, ipv4Src)
if err != nil {
return netip.Addr{}, netip.Addr{}, errors.Wrap(err, "failed to determine IPv6 source address for ICMP proxy")
}
if zone != "" {
logger.Info().Msgf("ICMP proxy will use %s in zone %s as source for IPv6", ipv6Src, zone)
} else {
logger.Info().Msgf("ICMP proxy will use %s as source for IPv6", ipv6Src)
}
return ipv4Src, ipv6Src, nil
}
func determineICMPv4Src(userDefinedSrc string, logger *zerolog.Logger) (netip.Addr, error) { func determineICMPv4Src(userDefinedSrc string, logger *zerolog.Logger) (netip.Addr, error) {
if userDefinedSrc != "" { if userDefinedSrc != "" {
addr, err := netip.ParseAddr(userDefinedSrc) addr, err := netip.ParseAddr(userDefinedSrc)

View File

@ -25,7 +25,7 @@ func helperCreateServer(t *testing.T, listeners *gracenet.Net, tunnelID uuid.UUI
require.NoError(t, err) require.NoError(t, err)
log := zerolog.Nop() log := zerolog.Nop()
tracker := tunnelstate.NewConnTracker(&log) tracker := tunnelstate.NewConnTracker(&log)
handler := diagnostic.NewDiagnosticHandler(&log, 0, nil, tunnelID, connectorID, tracker, nil, []string{}) handler := diagnostic.NewDiagnosticHandler(&log, 0, nil, tunnelID, connectorID, tracker, nil, []string{}, []string{})
router := http.NewServeMux() router := http.NewServeMux()
router.HandleFunc("/diag/tunnel", handler.TunnelStateHandler) router.HandleFunc("/diag/tunnel", handler.TunnelStateHandler)
server := &http.Server{ server := &http.Server{

View File

@ -26,6 +26,7 @@ type Handler struct {
tracker *tunnelstate.ConnTracker tracker *tunnelstate.ConnTracker
cli *cli.Context cli *cli.Context
flagInclusionList []string flagInclusionList []string
icmpSources []string
} }
func NewDiagnosticHandler( func NewDiagnosticHandler(
@ -37,6 +38,7 @@ func NewDiagnosticHandler(
tracker *tunnelstate.ConnTracker, tracker *tunnelstate.ConnTracker,
cli *cli.Context, cli *cli.Context,
flagInclusionList []string, flagInclusionList []string,
icmpSources []string,
) *Handler { ) *Handler {
logger := log.With().Logger() logger := log.With().Logger()
if timeout == 0 { if timeout == 0 {
@ -52,6 +54,7 @@ func NewDiagnosticHandler(
tracker: tracker, tracker: tracker,
cli: cli, cli: cli,
flagInclusionList: flagInclusionList, flagInclusionList: flagInclusionList,
icmpSources: icmpSources,
} }
} }
@ -105,6 +108,7 @@ type TunnelState struct {
TunnelID uuid.UUID `json:"tunnelID,omitempty"` TunnelID uuid.UUID `json:"tunnelID,omitempty"`
ConnectorID uuid.UUID `json:"connectorID,omitempty"` ConnectorID uuid.UUID `json:"connectorID,omitempty"`
Connections []tunnelstate.IndexedConnectionInfo `json:"connections,omitempty"` Connections []tunnelstate.IndexedConnectionInfo `json:"connections,omitempty"`
ICMPSources []string `json:"icmp_sources,omitempty"`
} }
func (handler *Handler) TunnelStateHandler(writer http.ResponseWriter, _ *http.Request) { func (handler *Handler) TunnelStateHandler(writer http.ResponseWriter, _ *http.Request) {
@ -117,6 +121,7 @@ func (handler *Handler) TunnelStateHandler(writer http.ResponseWriter, _ *http.R
handler.tunnelID, handler.tunnelID,
handler.connectorID, handler.connectorID,
handler.tracker.GetActiveConnections(), handler.tracker.GetActiveConnections(),
handler.icmpSources,
} }
encoder := json.NewEncoder(writer) encoder := json.NewEncoder(writer)

View File

@ -123,7 +123,7 @@ func TestSystemHandler(t *testing.T) {
t.Run(tCase.name, func(t *testing.T) { t.Run(tCase.name, func(t *testing.T) {
t.Parallel() t.Parallel()
handler := diagnostic.NewDiagnosticHandler(&log, 0, &SystemCollectorMock{}, uuid.New(), uuid.New(), nil, nil, nil) handler := diagnostic.NewDiagnosticHandler(&log, 0, &SystemCollectorMock{}, uuid.New(), uuid.New(), nil, nil, nil, nil)
recorder := httptest.NewRecorder() recorder := httptest.NewRecorder()
ctx := setCtxValuesForSystemCollector(tCase.systemInfo, tCase.rawInfo, tCase.err) ctx := setCtxValuesForSystemCollector(tCase.systemInfo, tCase.rawInfo, tCase.err)
request, err := http.NewRequestWithContext(ctx, http.MethodGet, "/diag/syste,", nil) request, err := http.NewRequestWithContext(ctx, http.MethodGet, "/diag/syste,", nil)
@ -156,6 +156,7 @@ func TestTunnelStateHandler(t *testing.T) {
tunnelID uuid.UUID tunnelID uuid.UUID
clientID uuid.UUID clientID uuid.UUID
connections []tunnelstate.IndexedConnectionInfo connections []tunnelstate.IndexedConnectionInfo
icmpSources []string
}{ }{
{ {
name: "case1", name: "case1",
@ -163,9 +164,10 @@ func TestTunnelStateHandler(t *testing.T) {
clientID: uuid.New(), clientID: uuid.New(),
}, },
{ {
name: "case2", name: "case2",
tunnelID: uuid.New(), tunnelID: uuid.New(),
clientID: uuid.New(), clientID: uuid.New(),
icmpSources: []string{"172.17.0.3", "::1"},
connections: []tunnelstate.IndexedConnectionInfo{{ connections: []tunnelstate.IndexedConnectionInfo{{
ConnectionInfo: tunnelstate.ConnectionInfo{ ConnectionInfo: tunnelstate.ConnectionInfo{
IsConnected: true, IsConnected: true,
@ -181,7 +183,17 @@ func TestTunnelStateHandler(t *testing.T) {
t.Run(tCase.name, func(t *testing.T) { t.Run(tCase.name, func(t *testing.T) {
t.Parallel() t.Parallel()
tracker := newTrackerFromConns(t, tCase.connections) tracker := newTrackerFromConns(t, tCase.connections)
handler := diagnostic.NewDiagnosticHandler(&log, 0, nil, tCase.tunnelID, tCase.clientID, tracker, nil, nil) handler := diagnostic.NewDiagnosticHandler(
&log,
0,
nil,
tCase.tunnelID,
tCase.clientID,
tracker,
nil,
nil,
tCase.icmpSources,
)
recorder := httptest.NewRecorder() recorder := httptest.NewRecorder()
handler.TunnelStateHandler(recorder, nil) handler.TunnelStateHandler(recorder, nil)
decoder := json.NewDecoder(recorder.Body) decoder := json.NewDecoder(recorder.Body)
@ -193,6 +205,7 @@ func TestTunnelStateHandler(t *testing.T) {
assert.Equal(t, tCase.tunnelID, response.TunnelID) assert.Equal(t, tCase.tunnelID, response.TunnelID)
assert.Equal(t, tCase.clientID, response.ConnectorID) assert.Equal(t, tCase.clientID, response.ConnectorID)
assert.Equal(t, tCase.connections, response.Connections) assert.Equal(t, tCase.connections, response.Connections)
assert.Equal(t, tCase.icmpSources, response.ICMPSources)
}) })
} }
} }
@ -237,7 +250,7 @@ func TestConfigurationHandler(t *testing.T) {
t.Parallel() t.Parallel()
ctx := buildCliContext(t, tCase.flags) ctx := buildCliContext(t, tCase.flags)
handler := diagnostic.NewDiagnosticHandler(&log, 0, nil, uuid.New(), uuid.New(), nil, ctx, []string{"b", "c", "d"}) handler := diagnostic.NewDiagnosticHandler(&log, 0, nil, uuid.New(), uuid.New(), nil, ctx, []string{"b", "c", "d"}, nil)
recorder := httptest.NewRecorder() recorder := httptest.NewRecorder()
handler.ConfigurationHandler(recorder, nil) handler.ConfigurationHandler(recorder, nil)
decoder := json.NewDecoder(recorder.Body) decoder := json.NewDecoder(recorder.Body)