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

merge of new k2 securityagent support after resolving merge conflicts #893

Merged
merged 11 commits into from
Apr 4, 2024
23 changes: 21 additions & 2 deletions v3/integrations/nrecho-v3/nrecho.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ func transactionName(c echo.Context) string {
// e := echo.New()
// // Add the nrecho middleware before other middlewares or routes:
// e.Use(nrecho.Middleware(app))
//
func Middleware(app *newrelic.Application) func(echo.HandlerFunc) echo.HandlerFunc {

if nil == app {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return next
Expand Down Expand Up @@ -93,3 +91,24 @@ func Middleware(app *newrelic.Application) func(echo.HandlerFunc) echo.HandlerFu
}
}
}

// WrapRouter extracts API endpoints from the echo instance passed to it
// which is used to detect application URL mapping(api-endpoints) for provable security.
// In this version of the integration, this wrapper is only necessary if you are using the New Relic security agent integration [https://github.com/newrelic/go-agent/tree/master/v3/integrations/nrsecurityagent],
// but it may be enhanced to provide additional functionality in future releases.
// e := echo.New()
// ....
// ....
// ....
//
// nrecho.WrapRouter(e)
//

func WrapRouter(engine *echo.Echo) {
if engine != nil && newrelic.IsSecurityAgentPresent() {
router := engine.Routes()
for _, r := range router {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", r.Path, r.Method, r.Name)
}
}
}
22 changes: 21 additions & 1 deletion v3/integrations/nrecho-v4/nrecho.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ func WithSkipper(skipper Skipper) ConfigOption {
// e := echo.New()
// // Add the nrecho middleware before other middlewares or routes:
// e.Use(nrecho.MiddlewareWithConfig(nrecho.Config{App: app}))
//
func Middleware(app *newrelic.Application, opts ...ConfigOption) func(echo.HandlerFunc) echo.HandlerFunc {
if app == nil {
return func(next echo.HandlerFunc) echo.HandlerFunc {
Expand Down Expand Up @@ -131,3 +130,24 @@ func Middleware(app *newrelic.Application, opts ...ConfigOption) func(echo.Handl
}
}
}

// WrapRouter extracts API endpoints from the echo instance passed to it
// which is used to detect application URL mapping(api-endpoints) for provable security.
// In this version of the integration, this wrapper is only necessary if you are using the New Relic security agent integration [https://github.com/newrelic/go-agent/tree/master/v3/integrations/nrsecurityagent],
// but it may be enhanced to provide additional functionality in future releases.
// e := echo.New()
// ....
// ....
// ....
//
// nrecho.WrapRouter(e)
//

func WrapRouter(engine *echo.Echo) {
if engine != nil && newrelic.IsSecurityAgentPresent() {
router := engine.Routes()
for _, r := range router {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", r.Path, r.Method, r.Name)
}
}
}
4 changes: 3 additions & 1 deletion v3/integrations/nrfasthttp/instrumentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ func WrapHandle(app *newrelic.Application, pattern string, handler fasthttp.Requ
if app == nil {
return pattern, handler
}

if newrelic.IsSecurityAgentPresent() {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", pattern, "*", internal.HandlerName(handler))
}
// add the wrapped function to the trace options as the source code reference point
// (but only if we know we're collecting CLM for this transaction and the user didn't already
// specify a different code location explicitly).
Expand Down
20 changes: 20 additions & 0 deletions v3/integrations/nrgin/nrgin.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,26 @@ func MiddlewareHandlerTxnNames(app *newrelic.Application) gin.HandlerFunc {
return middleware(app, false)
}

// WrapRouter extracts API endpoints from the router instance passed to it
// which is used to detect application URL mapping(api-endpoints) for provable security.
// In this version of the integration, this wrapper is only necessary if you are using the New Relic security agent integration [https://github.com/newrelic/go-agent/tree/master/v3/integrations/nrsecurityagent],
// but it may be enhanced to provide additional functionality in future releases.
// router := gin.Default()
// ....
// ....
// ....
//
// nrgin.WrapRouter(router)
//

func WrapRouter(engine *gin.Engine) {
if engine != nil && newrelic.IsSecurityAgentPresent() {
router := engine.Routes()
for _, r := range router {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", r.Path, r.Method, internal.HandlerName(r.HandlerFunc))
}
}
}
func middleware(app *newrelic.Application, useNewNames bool) gin.HandlerFunc {
return func(c *gin.Context) {
if app != nil {
Expand Down
32 changes: 32 additions & 0 deletions v3/integrations/nrgorilla/nrgorilla.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,35 @@ func Middleware(app *newrelic.Application) mux.MiddlewareFunc {
})
}
}

// WrapRouter extracts API endpoints from the router object passed to it
// which is used to detect application URL mapping(api-endpoints) for provable security.
// In this version of the integration, this wrapper is only necessary if you are using the New Relic security agent integration [https://github.com/newrelic/go-agent/tree/master/v3/integrations/nrsecurityagent],
// but it may be enhanced to provide additional functionality in future releases.
// r := mux.NewRouter()
// ....
// ....
// ....
//
// nrgorilla.WrapRouter(router)
//

func WrapRouter(router *mux.Router) {
if router != nil && newrelic.IsSecurityAgentPresent() {
router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
path, err1 := route.GetPathTemplate()
if err1 != nil {
return nil
}
methods, _ := route.GetMethods()
if len(methods) == 0 {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", path, "*", internal.HandlerName(route.GetHandler()))
} else {
for _, method := range methods {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", path, method, internal.HandlerName(route.GetHandler()))
}
}
return nil
})
}
}
47 changes: 25 additions & 22 deletions v3/integrations/nrhttprouter/nrhttprouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@
// httprouter.Router. Use an *nrhttprouter.Router in place of your
// *httprouter.Router. Example:
//
// package main
// package main
//
// import (
// "fmt"
// "net/http"
// "os"
// import (
// "fmt"
// "net/http"
// "os"
//
// "github.com/julienschmidt/httprouter"
// newrelic "github.com/newrelic/go-agent/v3/newrelic"
// "github.com/newrelic/go-agent/v3/integrations/nrhttprouter"
// )
// "github.com/julienschmidt/httprouter"
// newrelic "github.com/newrelic/go-agent/v3/newrelic"
// "github.com/newrelic/go-agent/v3/integrations/nrhttprouter"
// )
//
// func main() {
// cfg := newrelic.NewConfig("httprouter App", os.Getenv("NEW_RELIC_LICENSE_KEY"))
// app, _ := newrelic.NewApplication(cfg)
// func main() {
// cfg := newrelic.NewConfig("httprouter App", os.Getenv("NEW_RELIC_LICENSE_KEY"))
// app, _ := newrelic.NewApplication(cfg)
//
// // Create the Router replacement:
// router := nrhttprouter.New(app)
// // Create the Router replacement:
// router := nrhttprouter.New(app)
//
// router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// w.Write([]byte("welcome\n"))
// })
// router.GET("/hello/:name", (w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// w.Write([]byte(fmt.Sprintf("hello %s\n", ps.ByName("name"))))
// })
// http.ListenAndServe(":8000", router)
// }
// router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// w.Write([]byte("welcome\n"))
// })
// router.GET("/hello/:name", (w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// w.Write([]byte(fmt.Sprintf("hello %s\n", ps.ByName("name"))))
// })
// http.ListenAndServe(":8000", router)
// }
//
// Runnable example: https://github.com/newrelic/go-agent/tree/master/v3/integrations/nrhttprouter/example/main.go
package nrhttprouter
Expand Down Expand Up @@ -84,6 +84,9 @@ func (r *Router) handle(method string, path string, original httprouter.Handle)
}
}
r.Router.Handle(method, path, handle)
if newrelic.IsSecurityAgentPresent() {
newrelic.GetSecurityAgentInterface().SendEvent("API_END_POINTS", path, method, internal.HandlerName(original))
}
}

// DELETE replaces httprouter.Router.DELETE.
Expand Down
5 changes: 2 additions & 3 deletions v3/integrations/nrsecurityagent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrsecurityagent
go 1.19

require (
github.com/newrelic/csec-go-agent v1.0.0
github.com/newrelic/go-agent/v3 v3.31.0
github.com/newrelic/csec-go-agent v1.1.0
github.com/newrelic/go-agent/v3 v3.30.0
github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0
gopkg.in/yaml.v2 v2.4.0
)


replace github.com/newrelic/go-agent/v3 => ../..
16 changes: 16 additions & 0 deletions v3/internal/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"runtime"
"time"
)

Expand All @@ -26,3 +28,17 @@ func CompactJSONString(js string) string {
}
return buf.String()
}

// HandlerName return name of a function.
func HandlerName(h interface{}) string {
if h == nil {
return ""
}
t := reflect.ValueOf(h).Type()
if t.Kind() == reflect.Func {
if pointer := runtime.FuncForPC(reflect.ValueOf(h).Pointer()); pointer != nil {
return pointer.Name()
}
}
return ""
}
6 changes: 6 additions & 0 deletions v3/newrelic/instrumentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package newrelic

import (
"net/http"

"github.com/newrelic/go-agent/v3/internal"
)

// instrumentation.go contains helpers built on the lower level api.
Expand Down Expand Up @@ -42,6 +44,10 @@ func WrapHandle(app *Application, pattern string, handler http.Handler, options
// specify a different code location explicitly).
cache := NewCachedCodeLocation()

if IsSecurityAgentPresent() {
secureAgent.SendEvent("API_END_POINTS", pattern, "*", internal.HandlerName(handler))
}

return pattern, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var tOptions *traceOptSet
var txnOptionList []TraceOption
Expand Down
4 changes: 2 additions & 2 deletions v3/newrelic/secure_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// calls in this case, effectively removing the hooks from the running agent.
//
// If the nrsecureagent integration was initialized, it will register a real securityAgent
// value in the securityAgent varialble instead, thus "activating" the hooks.
// value in the securityAgent variable instead, thus "activating" the hooks.
var secureAgent securityAgent = noOpSecurityAgent{}

// GetSecurityAgentInterface returns the securityAgent value
Expand All @@ -20,7 +20,7 @@ var secureAgent securityAgent = noOpSecurityAgent{}
//
// Packages which need to make calls to secureAgent's methods
// may obtain the secureAgent value by calling this function.
// This avoids exposing the variable itself so it's not
// This avoids exposing the variable itself, so it's not
// writable externally and also sets up for the future if this
// ends up not being a global variable later.
func GetSecurityAgentInterface() securityAgent {
Expand Down
Loading