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

Enables System Tests for APIGW Inferred Spans for Golang #3964

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
23 changes: 22 additions & 1 deletion manifests/golang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,28 @@ tests/:
"*": irrelevant
net-http: missing_feature (Endpoint not implemented)
net-http-orchestrion: missing_feature (Endpoint not implemented)
test_inferred_proxy.py: missing_feature
test_inferred_proxy.py:
Test_AWS_API_Gateway_Inferred_Span_Creation:
"*": irrelevant
chi: v1.72.0
echo: v1.72.0
gin: v1.72.0
net-http: v1.72.0
net-http-orchestrion: v1.72.0
Test_AWS_API_Gateway_Inferred_Span_Creation_With_Distributed_Context:
"*": irrelevant
chi: v1.72.0
echo: v1.72.0
gin: v1.72.0
net-http: v1.72.0
net-http-orchestrion: v1.72.0
Test_AWS_API_Gateway_Inferred_Span_Creation_With_Error:
"*": irrelevant
chi: v1.72.0
echo: v1.72.0
gin: v1.72.0
net-http: v1.72.0
net-http-orchestrion: v1.72.0
test_otel_drop_in.py:
Test_Otel_Drop_In: missing_feature
otel/:
Expand Down
7 changes: 3 additions & 4 deletions tests/integrations/test_inferred_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,12 @@ def assert_api_gateway_span(testCase, span, path, status_code, is_distributed=Fa
assert (
span["service"] == "system-tests-api-gateway.com"
), "Inferred AWS API Gateway span expected service should equal 'system-tests-api-gateway.com'"
assert "span.kind" in span["meta"], "Inferred AWS API Gateway span meta should contain 'span.kind'"
assert (
span["meta"]["span.kind"] == "internal"
), "Inferred AWS API Gateway span meta span.kind should equal 'internal'"
assert "stage" in span["meta"], "Inferred AWS API Gateway span meta should contain 'stage'"
assert span["meta"]["stage"] == "staging", "Inferred AWS API Gateway span meta expected stage to be 'staging'"
assert "start" in span, "Inferred AWS API Gateway span should have 'startTime'"
assert (
span["metrics"]["_dd.inferred_span"] == 1
), "Inferred AWS API Gateway span meta expected _dd.inferred_span = 1"

# assert on HTTP tags
assert "http.method" in span["meta"], "Inferred AWS API Gateway span meta should contain 'http.method'"
Expand Down
25 changes: 25 additions & 0 deletions utils/build/docker/golang/app/chi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"math/rand"
Expand Down Expand Up @@ -305,6 +306,30 @@ func main() {
mux.HandleFunc("/requestdownstream", common.Requestdownstream)
mux.HandleFunc("/returnheaders", common.Returnheaders)

mux.HandleFunc("/inferred-proxy/span-creation", func(w http.ResponseWriter, r *http.Request) {
statusCodeStr := r.URL.Query().Get("status_code")
statusCode := 200
if statusCodeStr != "" {
var err error
statusCode, err = strconv.Atoi(statusCodeStr)
if err != nil {
statusCode = 400 // Bad request if conversion fails
}
}

// Log the request headers
fmt.Println("Received an API Gateway request")
for key, values := range r.Header {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}

// Send the response
w.WriteHeader(statusCode)
w.Write([]byte("ok"))
})

srv := &http.Server{
Addr: ":7777",
Handler: mux,
Expand Down
24 changes: 24 additions & 0 deletions utils/build/docker/golang/app/echo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"math/rand"
Expand Down Expand Up @@ -264,6 +265,29 @@ func main() {
return ctx.NoContent(200)
})

r.GET("/inferred-proxy/span-creation", func(ctx echo.Context) error {
statusCodeStr := ctx.Request().URL.Query().Get("status_code")
statusCode := 200
if statusCodeStr != "" {
var err error
statusCode, err = strconv.Atoi(statusCodeStr)
if err != nil {
statusCode = 400
return ctx.String(statusCode, "no inferred span")
}
}

// Log the request headers
fmt.Println("Received an API Gateway request")
for key, values := range ctx.Request().Header {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}

return ctx.NoContent(statusCode)
})

r.Any("/rasp/lfi", echoHandleFunc(rasp.LFI))
r.Any("/rasp/ssrf", echoHandleFunc(rasp.SSRF))
r.Any("/rasp/sqli", echoHandleFunc(rasp.SQLi))
Expand Down
25 changes: 25 additions & 0 deletions utils/build/docker/golang/app/gin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"math/rand"
Expand Down Expand Up @@ -240,6 +241,30 @@ func main() {
appsec.TrackUserLoginSuccessEvent(ctx.Request.Context(), user, map[string]string{}, tracer.WithUserSessionID(cookie.Value))
})

r.GET("/inferred-proxy/span-creation", func(ctx *gin.Context) {
statusCodeStr := ctx.Query("status_code")
statusCode := 200
if statusCodeStr != "" {
var err error
statusCode, err = strconv.Atoi(statusCodeStr)
if err != nil {
statusCode = 400
}
}

// Log the request headers
fmt.Println("Received an API Gateway request")
for key, values := range ctx.Request.Header {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}

// Send the response
ctx.Writer.WriteHeader(statusCode)
ctx.Writer.Write([]byte("ok"))
})

r.Any("/rasp/lfi", ginHandleFunc(rasp.LFI))
r.Any("/rasp/ssrf", ginHandleFunc(rasp.SSRF))
r.Any("/rasp/sqli", ginHandleFunc(rasp.SQLi))
Expand Down
24 changes: 24 additions & 0 deletions utils/build/docker/golang/app/net-http-orchestrion/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,30 @@ func main() {
appsec.TrackUserLoginSuccessEvent(r.Context(), user, map[string]string{}, tracer.WithUserSessionID(cookie.Value))
})

mux.HandleFunc("/inferred-proxy/span-creation", func(w http.ResponseWriter, r *http.Request) {
statusCodeStr := r.URL.Query().Get("status_code")
statusCode := 200
if statusCodeStr != "" {
var err error
statusCode, err = strconv.Atoi(statusCodeStr)
if err != nil {
statusCode = 400 // Bad request if conversion fails
}
}

// Log the request headers
fmt.Println("Received an API Gateway request")
for key, values := range r.Header {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}

// Send the response
w.WriteHeader(statusCode)
w.Write([]byte("ok"))
})

mux.HandleFunc("/requestdownstream", common.Requestdownstream)
mux.HandleFunc("/returnheaders", common.Returnheaders)

Expand Down
30 changes: 27 additions & 3 deletions utils/build/docker/golang/app/net-http/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
otelbaggage "go.opentelemetry.io/otel/baggage"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
oteltrace "go.opentelemetry.io/otel/trace"
otelbaggage "go.opentelemetry.io/otel/baggage"

"gopkg.in/DataDog/dd-trace-go.v1/appsec"
httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http"
Expand Down Expand Up @@ -550,7 +550,7 @@ func main() {

spanContext := oteltrace.SpanContextFromContext(ctx)
baggage := otelbaggage.FromContext(ctx)

base := 16
bitSize := 64
result := make(map[string]any, 4)
Expand All @@ -567,7 +567,7 @@ func main() {

result["tracestate"] = spanContext.TraceState().String()
result["baggage"] = baggage.String()

jsonData, err := json.Marshal(result)
if err != nil {
w.WriteHeader(422)
Expand Down Expand Up @@ -626,6 +626,30 @@ func main() {
appsec.TrackUserLoginSuccessEvent(r.Context(), user, map[string]string{}, tracer.WithUserSessionID(cookie.Value))
})

mux.HandleFunc("/inferred-proxy/span-creation", func(w http.ResponseWriter, r *http.Request) {
statusCodeStr := r.URL.Query().Get("status_code")
statusCode := 200
if statusCodeStr != "" {
var err error
statusCode, err = strconv.Atoi(statusCodeStr)
if err != nil {
statusCode = 400 // Bad request if conversion fails
}
}

// Log the request headers
fmt.Println("Received an API Gateway request")
for key, values := range r.Header {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}

zarirhamza marked this conversation as resolved.
Show resolved Hide resolved
// Send the response
w.WriteHeader(statusCode)
w.Write([]byte("ok"))
})

mux.HandleFunc("/requestdownstream", common.Requestdownstream)
mux.HandleFunc("/returnheaders", common.Returnheaders)

Expand Down
Loading