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

🐛 Back-port 0.3: Task.List() no longer include associations; Fix rich context leak. #699

Open
wants to merge 2 commits into
base: release-0.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions api/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import (
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
"os"
"sort"
"strconv"
"strings"

"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
qf "github.com/konveyor/tackle2-hub/api/filter"
Expand All @@ -13,12 +20,6 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/logger"
"io"
"net/http"
"os"
"sort"
"strconv"
"strings"
)

//
Expand Down Expand Up @@ -2143,7 +2144,7 @@ type AnalysisWriter struct {
//
// db returns a db client.
func (r *AnalysisWriter) db() (db *gorm.DB) {
rtx := WithContext(r.ctx)
rtx := RichContext(r.ctx)
db = rtx.DB.Debug()
return
}
Expand Down Expand Up @@ -2288,7 +2289,7 @@ type ReportWriter struct {
//
// db returns a db client.
func (r *ReportWriter) db() (db *gorm.DB) {
rtx := WithContext(r.ctx)
rtx := RichContext(r.ctx)
db = rtx.DB.Debug()
return
}
Expand Down
5 changes: 3 additions & 2 deletions api/auth.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package api

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/konveyor/tackle2-hub/auth"
"net/http"
)

//
Expand Down Expand Up @@ -102,7 +103,7 @@ type Login struct {
// been granted the necessary scope to access a resource.
func Required(scope string) func(*gin.Context) {
return func(ctx *gin.Context) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
token := ctx.GetHeader(Authorization)
request := &auth.Request{
Token: token,
Expand Down
21 changes: 11 additions & 10 deletions api/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"strconv"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
liberr "github.com/jortel/go-utils/error"
Expand All @@ -16,11 +21,7 @@ import (
"github.com/konveyor/tackle2-hub/model"
"gopkg.in/yaml.v2"
"gorm.io/gorm"
"io"
"sigs.k8s.io/controller-runtime/pkg/client"
"strconv"
"strings"
"time"
)

var Log = logr.WithName("api")
Expand All @@ -37,15 +38,15 @@ type BaseHandler struct{}
//
// DB return db client associated with the context.
func (h *BaseHandler) DB(ctx *gin.Context) (db *gorm.DB) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
db = rtx.DB.Debug()
return
}

//
// Client returns k8s client from the context.
func (h *BaseHandler) Client(ctx *gin.Context) (client client.Client) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
client = rtx.Client
return
}
Expand Down Expand Up @@ -136,7 +137,7 @@ func (h *BaseHandler) modBody(
//
// CurrentUser gets username from Keycloak auth token.
func (h *BaseHandler) CurrentUser(ctx *gin.Context) (user string) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
user = rtx.User
if user == "" {
Log.Info("Failed to get current user.")
Expand All @@ -150,7 +151,7 @@ func (h *BaseHandler) CurrentUser(ctx *gin.Context) (user string) {
func (h *BaseHandler) HasScope(ctx *gin.Context, scope string) (b bool) {
in := auth.BaseScope{}
in.With(scope)
rtx := WithContext(ctx)
rtx := RichContext(ctx)
for _, s := range rtx.Scopes {
b = s.Match(in.Resource, in.Method)
if b {
Expand Down Expand Up @@ -258,14 +259,14 @@ func (h *BaseHandler) Decoder(ctx *gin.Context, encoding string, r io.Reader) (d
//
// Status sets the status code.
func (h *BaseHandler) Status(ctx *gin.Context, code int) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
rtx.Status(code)
}

//
// Respond sets the response.
func (h *BaseHandler) Respond(ctx *gin.Context, code int, r interface{}) {
rtx := WithContext(ctx)
rtx := RichContext(ctx)
rtx.Respond(code, r)
}

Expand Down
5 changes: 3 additions & 2 deletions api/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package api
import (
"bytes"
"encoding/json"
"github.com/gin-gonic/gin"
"io"
"net/http"

"github.com/gin-gonic/gin"
)

//
Expand Down Expand Up @@ -64,7 +65,7 @@ func (h BatchHandler) create(ctx *gin.Context, create gin.HandlerFunc) {
return
}

rtx := WithContext(ctx)
rtx := RichContext(ctx)
bErr := BatchError{Message: "Create failed."}
for i := range resources {
b, _ := json.Marshal(resources[i])
Expand Down
40 changes: 26 additions & 14 deletions api/context.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package api

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/konveyor/tackle2-hub/auth"
"gorm.io/gorm"
"net/http"
"sigs.k8s.io/controller-runtime/pkg/client"
)

//
// Response values.
type Response struct {
Status int
Body interface{}
}

//
// Context custom settings.
type Context struct {
Expand All @@ -24,11 +32,15 @@ type Context struct {
Response Response
}

//
// Response values.
type Response struct {
Status int
Body interface{}
// Attach to gin context.
func (r *Context) Attach(ctx *gin.Context) {
r.Context = ctx
ctx.Set("RichContext", r)
}

// Detach from gin context
func (r *Context) Detach() {
delete(r.Context.Keys, "RichContext")
}

//
Expand All @@ -50,17 +62,17 @@ func (r *Context) Respond(status int, body interface{}) {
}

//
// WithContext is a rich context.
func WithContext(ctx *gin.Context) (n *Context) {
// RichContext returns a rich context attached to the gin context.
func RichContext(ctx *gin.Context) (rtx *Context) {
key := "RichContext"
object, found := ctx.Get(key)
if !found {
n = &Context{}
ctx.Set(key, n)
rtx = &Context{}
rtx.Attach(ctx)
} else {
n = object.(*Context)
rtx = object.(*Context)
}
n.Context = ctx
rtx.Context = ctx
return
}

Expand All @@ -72,7 +84,7 @@ func Transaction(ctx *gin.Context) {
http.MethodPut,
http.MethodPatch,
http.MethodDelete:
rtx := WithContext(ctx)
rtx := RichContext(ctx)
err := rtx.DB.Transaction(func(tx *gorm.DB) (err error) {
db := rtx.DB
rtx.DB = tx
Expand All @@ -96,7 +108,7 @@ func Transaction(ctx *gin.Context) {
func Render() gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Next()
rtx := WithContext(ctx)
rtx := RichContext(ctx)
if rtx.Response.Body != nil {
ctx.Negotiate(
rtx.Response.Status,
Expand Down
7 changes: 4 additions & 3 deletions api/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package api

import (
"errors"
"net/http"
"os"

"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/konveyor/tackle2-hub/api/filter"
"github.com/konveyor/tackle2-hub/api/sort"
"github.com/konveyor/tackle2-hub/model"
"github.com/mattn/go-sqlite3"
"gorm.io/gorm"
"net/http"
"os"
)

//
Expand Down Expand Up @@ -92,7 +93,7 @@ func ErrorHandler() gin.HandlerFunc {

err := ctx.Errors[0]

rtx := WithContext(ctx)
rtx := RichContext(ctx)
if errors.Is(err, &BadRequestError{}) ||
errors.Is(err, &filter.Error{}) ||
errors.Is(err, &sort.SortError{}) ||
Expand Down
14 changes: 7 additions & 7 deletions api/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ package api

import (
"encoding/json"
"io/ioutil"
"net/http"
"sort"
"strconv"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/konveyor/tackle2-hub/model"
tasking "github.com/konveyor/tackle2-hub/task"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"io/ioutil"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/utils/strings/slices"
"net/http"
"sort"
"strconv"
"strings"
"time"
)

//
Expand Down Expand Up @@ -114,7 +115,6 @@ func (h TaskHandler) List(ctx *gin.Context) {
if locator != "" {
db = db.Where("locator", locator)
}
db = db.Preload(clause.Associations)
result := db.Find(&list)
if result.Error != nil {
_ = ctx.Error(result.Error)
Expand Down
13 changes: 8 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package main

import (
"context"
"net/http"
"syscall"

"github.com/gin-gonic/gin"
liberr "github.com/jortel/go-utils/error"
"github.com/jortel/go-utils/logr"
Expand All @@ -21,10 +24,8 @@ import (
"github.com/konveyor/tackle2-hub/tracker"
"gorm.io/gorm"
"k8s.io/client-go/kubernetes/scheme"
"net/http"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/manager"
"syscall"
)

var Settings = &settings.Settings
Expand Down Expand Up @@ -195,14 +196,16 @@ func main() {
}
// Web
router := gin.Default()
router.Use(api.Render())
router.Use(api.ErrorHandler())
router.Use(
func(ctx *gin.Context) {
rtx := api.WithContext(ctx)
rtx := api.RichContext(ctx)
rtx.DB = db
rtx.Client = client
ctx.Next()
rtx.Detach()
})
router.Use(api.Render())
router.Use(api.ErrorHandler())
for _, h := range api.All() {
h.AddRoutes(router)
}
Expand Down
Loading