Skip to content

Commit

Permalink
Standardize old resources to to use list method with SQL Injection pr…
Browse files Browse the repository at this point in the history
…otection and stardardize PollingProfile file (#2839)

* wip: update list on demo and environment to use the same standards as tests and transactions

* Fixing provisioning test

* Update provisioning test
  • Loading branch information
danielbdias committed Jun 29, 2023
1 parent 8ea0ffe commit 892e3da
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 120 deletions.
2 changes: 1 addition & 1 deletion server/Makefile
Expand Up @@ -18,7 +18,7 @@ init-submodule:
git submodule init
git submodule update

test: # run go tests for this application
test: ## run go tests for this application
go test -timeout 150s -coverprofile=coverage.out ./...

vet: ## run vet tool to analyze the code for suspicious, abnormal, or useless code
Expand Down
37 changes: 21 additions & 16 deletions server/config/demo/demo_repository.go
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"

"github.com/kubeshop/tracetest/server/pkg/id"
"github.com/kubeshop/tracetest/server/pkg/sqlutil"
"github.com/kubeshop/tracetest/server/resourcemanager"
)

Expand Down Expand Up @@ -182,30 +183,34 @@ func (r Repository) SortingFields() []string {
return []string{"id", "name", "type"}
}

func (r *Repository) List(ctx context.Context, take, skip int, query, sortBy, sortDirection string) ([]Demo, error) {
listQuery := baseSelect
func listQuery(baseSQL, query string, params []any) (string, []any) {
paramNumber := len(params) + 1
condition := fmt.Sprintf(" AND (t.name ilike $%d)", paramNumber)

if sortDirection == "" {
sortDirection = "ASC"
}
sql, params := sqlutil.Search(baseSQL, condition, query, params)

if query != "" {
listQuery = fmt.Sprintf("%s WHERE %s", listQuery, query)
}
return sql, params
}

if sortBy != "" {
listQuery = fmt.Sprintf("%s ORDER BY %s %s", listQuery, sortBy, sortDirection)
}
func (r *Repository) List(ctx context.Context, take, skip int, query, sortBy, sortDirection string) ([]Demo, error) {
q, params := listQuery(baseSelect, query, []any{take, skip})

if take > 0 {
listQuery = fmt.Sprintf("%s LIMIT %d", listQuery, take)
sortingFields := map[string]string{
"id": "id",
"name": "name",
"type": "type",
}

if skip > 0 {
listQuery = fmt.Sprintf("%s OFFSET %d", listQuery, skip)
q = sqlutil.Sort(q, sortBy, sortDirection, "name", sortingFields)
q += " LIMIT $1 OFFSET $2"

stmt, err := r.db.Prepare(q)
if err != nil {
return nil, err
}
defer stmt.Close()

rows, err := r.db.QueryContext(ctx, listQuery)
rows, err := stmt.QueryContext(ctx, params...)
if err != nil {
return nil, fmt.Errorf("sql query: %w", err)
}
Expand Down
22 changes: 12 additions & 10 deletions server/environment/environment_repository.go
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/kubeshop/tracetest/server/pkg/id"
"github.com/kubeshop/tracetest/server/pkg/sqlutil"
)

type Repository struct {
Expand Down Expand Up @@ -119,27 +120,28 @@ func (r *Repository) Delete(ctx context.Context, id id.ID) error {
return nil
}

func listQuery(baseSQL, query string, params []any) (string, []any) {
paramNumber := len(params) + 1
condition := fmt.Sprintf(" AND (t.name ilike $%d OR e.description ilike $%d)", paramNumber, paramNumber)

sql, params := sqlutil.Search(baseSQL, condition, query, params)

return sql, params
}

func (r *Repository) List(ctx context.Context, take, skip int, query, sortBy, sortDirection string) ([]Environment, error) {
if take == 0 {
take = 20
}

params := []any{take, skip}

sql := getQuery

const condition = "WHERE (e.name ilike $3 OR e.description ilike $3) "
if query != "" {
sql += condition
params = append(params, query)
}
sql, params := listQuery(getQuery, query, []any{take, skip})

sortingFields := map[string]string{
"created": "e.created_at",
"name": "e.name",
}

sql = sortQuery(sql, sortBy, sortDirection, sortingFields)
sql = sqlutil.Sort(sql, sortBy, sortDirection, "created", sortingFields)
sql += ` LIMIT $1 OFFSET $2 `

stmt, err := r.db.Prepare(sql)
Expand Down
100 changes: 100 additions & 0 deletions server/executor/pollingprofile/polling_profile_entities.go
@@ -0,0 +1,100 @@
package pollingprofile

import (
"fmt"
"math"
"time"

"github.com/kubeshop/tracetest/server/pkg/id"
"github.com/kubeshop/tracetest/server/resourcemanager"
)

type Strategy string

const (
Periodic Strategy = "periodic"
)

const (
ResourceName = "PollingProfile"
ResourceNamePlural = "PollingProfiles"
)

var Operations = []resourcemanager.Operation{
resourcemanager.OperationGet,
resourcemanager.OperationList,
resourcemanager.OperationUpdate,
}

var DefaultPollingProfile = PollingProfile{
ID: id.ID("current"),
Name: "default",
Default: true,
Strategy: Periodic,
Periodic: &PeriodicPollingConfig{
Timeout: "1m",
RetryDelay: "5s",
},
}

type PollingProfile struct {
ID id.ID `json:"id"`
Name string `json:"name"`
Default bool `json:"default"`
Strategy Strategy `json:"strategy"`
Periodic *PeriodicPollingConfig `json:"periodic"`
}

type PeriodicPollingConfig struct {
RetryDelay string `json:"retryDelay"`
Timeout string `json:"timeout"`
SelectorMatchRetries int `json:"selectorMatchRetries"`
}

func (ppc *PeriodicPollingConfig) TimeoutDuration() time.Duration {
d, _ := time.ParseDuration(ppc.Timeout)
return d
}

func (ppc *PeriodicPollingConfig) RetryDelayDuration() time.Duration {
d, _ := time.ParseDuration(ppc.RetryDelay)
return d
}

func (ppc *PeriodicPollingConfig) MaxTracePollRetry() int {
return int(math.Ceil(float64(ppc.TimeoutDuration()) / float64(ppc.RetryDelayDuration())))
}

func (ppc *PeriodicPollingConfig) Validate() error {
if ppc == nil {
return fmt.Errorf("missing periodic polling profile configuration")
}

if _, err := time.ParseDuration(ppc.RetryDelay); err != nil {
return fmt.Errorf("retry delay configuration is invalid: %w", err)
}

if _, err := time.ParseDuration(ppc.Timeout); err != nil {
return fmt.Errorf("timeout configuration is invalid: %w", err)
}

return nil
}

func (pp PollingProfile) HasID() bool {
return pp.ID.String() != ""
}

func (pp PollingProfile) GetID() id.ID {
return pp.ID
}

func (pp PollingProfile) Validate() error {
if pp.Strategy == Periodic {
if err := pp.Periodic.Validate(); err != nil {
return err
}
}

return nil
}
Expand Up @@ -6,103 +6,10 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"time"

"github.com/kubeshop/tracetest/server/pkg/id"
"github.com/kubeshop/tracetest/server/resourcemanager"
)

type Strategy string

const (
Periodic Strategy = "periodic"
)

const (
ResourceName = "PollingProfile"
ResourceNamePlural = "PollingProfiles"
)

var Operations = []resourcemanager.Operation{
resourcemanager.OperationGet,
resourcemanager.OperationList,
resourcemanager.OperationUpdate,
}

var DefaultPollingProfile = PollingProfile{
ID: id.ID("current"),
Name: "default",
Default: true,
Strategy: Periodic,
Periodic: &PeriodicPollingConfig{
Timeout: "1m",
RetryDelay: "5s",
},
}

type PollingProfile struct {
ID id.ID `json:"id"`
Name string `json:"name"`
Default bool `json:"default"`
Strategy Strategy `json:"strategy"`
Periodic *PeriodicPollingConfig `json:"periodic"`
}

type PeriodicPollingConfig struct {
RetryDelay string `json:"retryDelay"`
Timeout string `json:"timeout"`
SelectorMatchRetries int `json:"selectorMatchRetries"`
}

func (ppc *PeriodicPollingConfig) TimeoutDuration() time.Duration {
d, _ := time.ParseDuration(ppc.Timeout)
return d
}

func (ppc *PeriodicPollingConfig) RetryDelayDuration() time.Duration {
d, _ := time.ParseDuration(ppc.RetryDelay)
return d
}

func (ppc *PeriodicPollingConfig) MaxTracePollRetry() int {
return int(math.Ceil(float64(ppc.TimeoutDuration()) / float64(ppc.RetryDelayDuration())))
}

func (ppc *PeriodicPollingConfig) Validate() error {
if ppc == nil {
return fmt.Errorf("missing periodic polling profile configuration")
}

if _, err := time.ParseDuration(ppc.RetryDelay); err != nil {
return fmt.Errorf("retry delay configuration is invalid: %w", err)
}

if _, err := time.ParseDuration(ppc.Timeout); err != nil {
return fmt.Errorf("timeout configuration is invalid: %w", err)
}

return nil
}

func (pp PollingProfile) HasID() bool {
return pp.ID.String() != ""
}

func (pp PollingProfile) GetID() id.ID {
return pp.ID
}

func (pp PollingProfile) Validate() error {
if pp.Strategy == Periodic {
if err := pp.Periodic.Validate(); err != nil {
return err
}
}

return nil
}

func NewRepository(db *sql.DB) *Repository {
return &Repository{db}
}
Expand Down

0 comments on commit 892e3da

Please sign in to comment.