Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: alert about localhost when trigger is running inside container #3124

Merged
merged 2 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
71 changes: 71 additions & 0 deletions server/executor/trigger_executer_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package executor

import (
"context"
"errors"
"fmt"
"net/url"
"os"
"strings"

"github.com/kubeshop/tracetest/server/analytics"
triggerer "github.com/kubeshop/tracetest/server/executor/trigger"
"github.com/kubeshop/tracetest/server/model/events"
"github.com/kubeshop/tracetest/server/test"
"github.com/kubeshop/tracetest/server/test/trigger"
"go.opentelemetry.io/otel/trace"
)

Expand Down Expand Up @@ -66,6 +71,15 @@ func (r triggerExecuterWorker) ProcessItem(ctx context.Context, job Job) {
response, err := triggererObj.Trigger(ctx, job.Test, &triggerer.TriggerOptions{
TraceID: run.TraceID,
})
if err != nil {
response.Result.Error = &trigger.TriggerError{
ConnectionError: isConnectionError(err),
RunningOnContainer: isServerRunningInsideContainer(),
TargetsLocalhost: isTargetLocalhost(job.Test.Trigger),
ErrorMessage: err.Error(),
}
}

run = r.handleExecutionResult(run, response, err)
run.SpanID = response.SpanID

Expand All @@ -89,3 +103,60 @@ func (r triggerExecuterWorker) handleExecutionResult(run test.Run, response trig

return run.SuccessfullyTriggered()
}

func isConnectionError(err error) bool {
for err != nil {
// a dial error means we couldn't open a TCP connection (either host is not available or DNS doesn't exist)
if strings.HasPrefix(err.Error(), "dial ") {
return true
}

// it means a trigger timeout
if errors.Is(err, context.DeadlineExceeded) {
return true
}

err = errors.Unwrap(err)
}

return false
}

func isTargetLocalhost(t trigger.Trigger) bool {
var endpoint string
switch t.Type {
case trigger.TriggerTypeHTTP:
endpoint = t.HTTP.URL
case trigger.TriggerTypeGRPC:
endpoint = t.GRPC.Address
}

url, err := url.Parse(endpoint)
if err != nil {
return false
}

// removes port
host := url.Host
colonPosition := strings.Index(url.Host, ":")
if colonPosition >= 0 {
host = host[0:colonPosition]
}

return host == "localhost" || host == "127.0.0.1"
}

func isServerRunningInsideContainer() bool {
// Check if running on Docker
// Reference: https://paulbradley.org/indocker/
if _, err := os.Stat("/.dockerenv"); err == nil {
return true
}

// Check if running on k8s
if os.Getenv("KUBERNETES_SERVICE_HOST") != "" {
return true
}

return false
}
28 changes: 1 addition & 27 deletions server/executor/trigger_result_processor_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package executor
import (
"context"
"fmt"
"net/url"
"strings"

"github.com/kubeshop/tracetest/server/model"
"github.com/kubeshop/tracetest/server/model/events"
Expand Down Expand Up @@ -64,7 +62,7 @@ func (r triggerResultProcessorWorker) ProcessItem(ctx context.Context, job Job)
if triggerResult.Error.ConnectionError {
r.emitUnreachableEndpointEvent(ctx, job, err)

if isTargetLocalhost(job) && triggerResult.Error.RunningOnContainer {
if triggerResult.Error.TargetsLocalhost && triggerResult.Error.RunningOnContainer {
r.emitMismatchEndpointEvent(ctx, job, err)
}
}
Expand Down Expand Up @@ -111,27 +109,3 @@ func (r triggerResultProcessorWorker) emitMismatchEndpointEvent(ctx context.Cont
r.handleError(job.Run, emitErr)
}
}

func isTargetLocalhost(job Job) bool {
var endpoint string
switch job.Test.Trigger.Type {
case trigger.TriggerTypeHTTP:
endpoint = job.Test.Trigger.HTTP.URL
case trigger.TriggerTypeGRPC:
endpoint = job.Test.Trigger.GRPC.Address
}

url, err := url.Parse(endpoint)
if err != nil {
return false
}

// removes port
host := url.Host
colonPosition := strings.Index(url.Host, ":")
if colonPosition >= 0 {
host = host[0:colonPosition]
}

return host == "localhost" || host == "127.0.0.1"
}
1 change: 1 addition & 0 deletions server/test/trigger/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type (
TriggerError struct {
ConnectionError bool `json:"connectionError"`
RunningOnContainer bool `json:"runningOnContainer"`
TargetsLocalhost bool `json:"targetsLocalhost"`
ErrorMessage string `json:"message"`
}
)
Expand Down