Skip to content

Commit

Permalink
Merge pull request newrelic#893 from nr-swilloughby/develop
Browse files Browse the repository at this point in the history
merge of new k2 securityagent support after resolving merge conflicts
  • Loading branch information
nr-swilloughby authored Apr 4, 2024
2 parents 4134348 + 51f5283 commit e5cab8d
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 31 deletions.
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

0 comments on commit e5cab8d

Please sign in to comment.