Skip to content

Commit

Permalink
RHINENG-3098: deprecate limit=-1 and limit>100
Browse files Browse the repository at this point in the history
  • Loading branch information
psegedy committed Dec 15, 2023
1 parent 7910d97 commit d46a93b
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 8 deletions.
45 changes: 37 additions & 8 deletions base/deprecations/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ type apiDeprecation struct {
message string
}

type limitDeprecation struct {
shouldDeprecate func(c *gin.Context) bool
deprecationTimestamp time.Time
message string
}

func (d limitDeprecation) Deprecate(c *gin.Context) {
if !utils.Cfg.LimitPageSize || !d.shouldDeprecate(c) {
return
}

now := time.Now()
httpDate := d.deprecationTimestamp.Format(time.RFC1123)
setDeprecationHeader(c, httpDate, d.message)

if now.Before(d.deprecationTimestamp) {
// allow unlimited `limit`
utils.Cfg.LimitPageSize = false
c.Next()
// reset LimitPageSize after all midllewares
utils.Cfg.LimitPageSize = true
}
}

func (d apiDeprecation) Deprecate(c *gin.Context) {
if !d.shouldDeprecate(c) {
return
Expand All @@ -48,14 +72,7 @@ func (d apiDeprecation) Deprecate(c *gin.Context) {
func (d *apiDeprecation) setDeprecationHeader(c *gin.Context) {
// RFC1123 is HTTP-date format
httpDate := d.deprecationTimestamp.Format(time.RFC1123)

// set Deprecation header
// https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header
c.Header("Deprecation", httpDate)

// set Sunset header
// https://datatracker.ietf.org/doc/html/rfc8594
c.Header("Sunset", httpDate)
setDeprecationHeader(c, httpDate, d.message)
}

func (d *apiDeprecation) redirect(c *gin.Context) {
Expand All @@ -79,3 +96,15 @@ func (d *apiDeprecation) redirect(c *gin.Context) {
func (d *apiDeprecation) gone(c *gin.Context) {
c.AbortWithStatusJSON(http.StatusGone, utils.ErrorResponse{Error: d.message})
}

func setDeprecationHeader(c *gin.Context, httpDate string, message string) {
c.Header("Warning", message)

// set Deprecation header
// https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header
c.Header("Deprecation", httpDate)

// set Sunset header
// https://datatracker.ietf.org/doc/html/rfc8594
c.Header("Sunset", httpDate)
}
15 changes: 15 additions & 0 deletions base/deprecations/deprecations.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,18 @@ func DeprecateV1V2APIs() Deprecation {
},
}
}

// Deprecate maximum `limit`
func DeprecateLimit() Deprecation {
return limitDeprecation{
deprecationTimestamp: time.Date(2024, 3, 1, 0, 0, 0, 0, time.UTC),
message: "limit must be in [1, 100]",
shouldDeprecate: func(c *gin.Context) bool {
limit, err := utils.LoadParamInt(c, "limit", 20, true)
if err == nil && (limit < 1 || limit > 100) {
return true
}
return false
},
}
}
2 changes: 2 additions & 0 deletions base/utils/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Config struct {
MaxHeaderCount int
MaxGinConnections int
Ratelimit int
LimitPageSize bool

// kafka
KafkaServers []string
Expand Down Expand Up @@ -177,6 +178,7 @@ func initAPIromClowder() {
Cfg.MaxHeaderCount = GetIntEnvOrDefault("MAX_HEADER_COUNT", 50)
Cfg.MaxGinConnections = GetIntEnvOrDefault("MAX_GIN_CONNECTIONS", 50)
Cfg.Ratelimit = GetIntEnvOrDefault("RATELIMIT", 100)
Cfg.LimitPageSize = GetBoolEnvOrDefault("LIMIT_PAGE_SIZE", true)
}

func initKafkaFromClowder() {
Expand Down
5 changes: 5 additions & 0 deletions base/utils/gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ func CheckLimitOffset(limit int, offset int) error {
if offset < 0 {
return errors.New("offset must not be negative")
}
if Cfg.LimitPageSize {
if limit < 1 || limit > 100 {
return errors.New("limit must be in [1, 100]")
}
}
if limit < 1 && limit != -1 {
return errors.New("limit must not be less than 1, or should be -1 to return all items")
}
Expand Down
1 change: 1 addition & 0 deletions conf/test.env
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ MAX_EVAL_GOROUTINES=1
SCHEMA_MIGRATION=-1
# don't retry vmaas calls forever
VMAAS_CALL_MAX_RETRIES=100
LIMIT_PAGE_SIZE=false
2 changes: 2 additions & 0 deletions deploy/clowdapp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ objects:
- {name: MAX_HEADER_COUNT, value: '${MAX_HEADER_COUNT}'}
- {name: MAX_GIN_CONNECTIONS, value: '${MAX_GIN_CONNECTIONS}'}
- {name: RATELIMIT, value: '${RATELIMIT}'}
- {name: LIMIT_PAGE_SIZE, value: '${LIMIT_PAGE_SIZE}'}

resources:
limits: {cpu: '${RES_LIMIT_CPU_MANAGER}', memory: '${RES_LIMIT_MEM_MANAGER}'}
Expand Down Expand Up @@ -594,6 +595,7 @@ parameters:
- {name: MAX_HEADER_COUNT, value: '50'} # limit number of request headers
- {name: MAX_GIN_CONNECTIONS, value: '50'}
- {name: RATELIMIT, value: '100'} # requests per second for leaky bucket rate limiter
- {name: LIMIT_PAGE_SIZE, value: 'true'} # page size is limited to 100 items per page, set to `false` to use any limit

# Listener
- {name: REPLICAS_LISTENER, value: '1'}
Expand Down
1 change: 1 addition & 0 deletions manager/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func InitAPI(api *gin.RouterGroup, config docs.EndpointsConfig) { // nolint: fun
api.Use(middlewares.CheckReferer())
api.Use(middlewares.SetAPIVersion(api.BasePath()))
api.Use(middlewares.Deprecate(deprecations.DeprecateV1V2APIs()))
api.Use(middlewares.Deprecate(deprecations.DeprecateLimit()))
api.Use(middlewares.DatabaseWithContext())

advisories := api.Group("/advisories")
Expand Down

0 comments on commit d46a93b

Please sign in to comment.