Skip to content

Commit

Permalink
Merge branch 'master' into bugfix/TT-6968
Browse files Browse the repository at this point in the history
  • Loading branch information
tbuchaillot committed Dec 30, 2022
2 parents 75fb104 + f2c10b9 commit 52f3b3f
Show file tree
Hide file tree
Showing 24 changed files with 375 additions and 73 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/api-tests.yml
Expand Up @@ -2,11 +2,9 @@ name: API integration Tests

on:
pull_request:
push:
branches:
- master
- test/*
- release-*
- release-**

env:
GOPRIVATE: github.com/TykTechnologies
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/ci-tests.yml
Expand Up @@ -2,8 +2,9 @@ name: CI tests

on:
pull_request:
push:
branches: [master]
branches:
- master
- release-**

env:
TYK_DB_REDISHOST: localhost
Expand Down Expand Up @@ -110,11 +111,6 @@ jobs:
run: |
$(go env GOPATH)/bin/golangci-lint run --out-format checkstyle --issues-exit-code=0 --new-from-rev=origin/${{ github.base_ref }} ./... > golanglint.xml
- name: golangci-lint
if: ${{ github.event_name == 'push' }}
run: |
$(go env GOPATH)/bin/golangci-lint run --out-format checkstyle --issues-exit-code=0 ./... > golanglint.xml
- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@master
with:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/codeql-analysis.yml
Expand Up @@ -6,10 +6,7 @@
name: "CodeQL"

on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: '0 18 * * 4'
Expand Down
32 changes: 0 additions & 32 deletions .github/workflows/golangci-lint.yml

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/release.yml
Expand Up @@ -16,7 +16,6 @@ name: Release

on:
pull_request:
push:
branches:
- master
- release-**
Expand Down
37 changes: 37 additions & 0 deletions .golangci.yml
Expand Up @@ -64,3 +64,40 @@ run:
# Mainly related to generics support since go1.18.
# Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.18
go: '1.16'

linters:
disable:
- varnamelen
- tagliatelle
- testpackage
- paralleltest
- forbidigo
- ireturn
- goerr113
enable:
- thelper
- errcheck
- errorlint
- noctx
- dupl
- nilerr
- misspell

linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
exclude-functions:
- (*github.com/TykTechnologies/tyk/gateway.Test).Run

issues:
exclude-rules:
- path: _test\.go
linters:
- dupl # many functions looks like dupes
- gocyclo # many functions can be very long
- funlen # many functions can be very long
- gosec # tests don't have CVEs
exclude:
- G404 # Use of weak random number generator (math/rand instead of crypto/rand)
- SA9004 # only the first constant in this group has an explicit type
10 changes: 5 additions & 5 deletions config/config.go
Expand Up @@ -221,7 +221,7 @@ type HealthCheckConfig struct {
}

type LivenessCheckConfig struct {
// Frequence of performing interval healthchecks for Redis, Dashboard, and RPC layer. Default: 10 seconds.
// Frequencies of performing interval healthchecks for Redis, Dashboard, and RPC layer. Default: 10 seconds.
CheckDuration time.Duration `json:"check_duration"`
}

Expand Down Expand Up @@ -559,10 +559,10 @@ type Config struct {
// was written.
OriginalPath string `json:"-"`

// Force your Gateway to work only on a specifc domain name. Can be overriden by API custom domain.
// Force your Gateway to work only on a specific domain name. Can be overridden by API custom domain.
HostName string `json:"hostname"`

// If your machine has mulitple network devices or IPs you can force the Gateway to use the IP address you want.
// If your machine has multiple network devices or IPs you can force the Gateway to use the IP address you want.
ListenAddress string `json:"listen_address"`

// Setting this value will change the port that Tyk listens on. Default: 8080.
Expand Down Expand Up @@ -685,7 +685,7 @@ type Config struct {
// The standard rate limiter offers similar performance as the sentinel-based limiter. This is disabled by default.
EnableSentinelRateLimiter bool `json:"enable_sentinel_rate_limiter"`

// An enchancment for the Redis and Sentinel rate limiters, that offers a significant improvement in performance by not using transactions on Redis rate-limit buckets.
// An enhancement for the Redis and Sentinel rate limiters, that offers a significant improvement in performance by not using transactions on Redis rate-limit buckets.
EnableNonTransactionalRateLimiter bool `json:"enable_non_transactional_rate_limiter"`

// How frequently a distributed rate limiter synchronises information between the Gateway nodes. Default: 2 seconds.
Expand Down Expand Up @@ -970,7 +970,7 @@ type Config struct {
// global session lifetime, in seconds.
GlobalSessionLifetime int64 `bson:"global_session_lifetime" json:"global_session_lifetime"`

// This section enables the use of the KV capabilites to substitute configuration values.
// This section enables the use of the KV capabilities to substitute configuration values.
// See more details https://tyk.io/docs/tyk-configuration-reference/kv-store/
KV struct {
Consul ConsulConfig `json:"consul"`
Expand Down
50 changes: 50 additions & 0 deletions gateway/analytics_test.go
Expand Up @@ -58,6 +58,7 @@ func TestAnalytics_Write(t *testing.T) {
{Path: "/", Code: 401},
{Path: "/", Code: 401},
}...)

if err != nil {
t.Error("Error executing test case")
}
Expand Down Expand Up @@ -404,6 +405,55 @@ func TestAnalytics_Write(t *testing.T) {
}
})

t.Run("Upstream error analytics", func(t *testing.T) {
defer func() {
ts.Gw.SetConfig(base)
}()
ls := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}))
defer ls.Close()

ts.Gw.BuildAndLoadAPI(func(spec *APISpec) {
spec.UseKeylessAccess = false
spec.Proxy.ListenPath = "/"
spec.Proxy.TargetURL = ls.URL
})

key := CreateSession(ts.Gw)

authHeaders := map[string]string{
"authorization": key,
}

client := http.Client{
Timeout: 1 * time.Millisecond,
}
_, err := ts.Run(t, test.TestCase{
Path: "/", Headers: authHeaders, Code: 499, Client: &client, ErrorMatch: "context deadline exceeded",
})
assert.NotNil(t, err)

// we wait until the request finish
time.Sleep(3 * time.Millisecond)
// let records to to be sent
ts.Gw.Analytics.Flush()

results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName)
assert.Len(t, results, 1)

var record analytics.AnalyticsRecord
err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record)
assert.Nil(t, err)

// expect a status 499 (context canceled) from the request
assert.Equal(t, 499, record.ResponseCode)
// expect that the analytic record maintained the APIKey
assert.Equal(t, key, record.APIKey)

})

})
}

Expand Down
43 changes: 41 additions & 2 deletions gateway/api.go
Expand Up @@ -1286,6 +1286,45 @@ func (gw *Gateway) handleDeleteAPI(apiID string) (interface{}, int) {
os.Remove(defOASFilePath)
}

if spec.VersionDefinition.BaseID != "" {
baseAPIPtr := gw.getApiSpec(spec.VersionDefinition.BaseID)
apiInBytes, err := json.Marshal(baseAPIPtr)
if err != nil {
log.WithError(err).Error("Couldn't marshal API spec")
}

var baseAPI APISpec
err = json.Unmarshal(apiInBytes, &baseAPI)
if err != nil {
log.WithError(err).Error("Couldn't unmarshal API spec")
}

for versionName, versionAPIID := range baseAPI.VersionDefinition.Versions {
if apiID == versionAPIID {
delete(baseAPI.VersionDefinition.Versions, versionName)
if baseAPI.VersionDefinition.Default == versionName {
baseAPI.VersionDefinition.Default = baseAPI.VersionDefinition.Name
}

break
}
}

fs := afero.NewOsFs()
if baseAPI.IsOAS {
baseAPI.OAS.Fill(*baseAPI.APIDefinition)
err, _ := gw.writeOASAndAPIDefToFile(fs, baseAPI.APIDefinition, &baseAPI.OAS)
if err != nil {
log.WithError(err).Errorf("Error occurred while updating base OAS API with id: %s", baseAPI.APIID)
}
} else {
err, _ := gw.writeToFile(fs, baseAPI.APIDefinition, baseAPI.APIID)
if err != nil {
log.WithError(err).Errorf("Error occurred while updating base API with id: %s", baseAPI.APIID)
}
}
}

response := apiModifyKeySuccess{
Key: apiID,
Status: "ok",
Expand Down Expand Up @@ -1339,7 +1378,7 @@ func (gw *Gateway) apiHandler(w http.ResponseWriter, r *http.Request) {
var code int

switch r.Method {
case "GET":
case http.MethodGet:
if apiID != "" {
log.Debugf("Requesting API definition for %q", apiID)
obj, code = gw.handleGetAPI(apiID, false)
Expand All @@ -1363,7 +1402,7 @@ func (gw *Gateway) apiHandler(w http.ResponseWriter, r *http.Request) {
} else {
obj, code = apiError("Must specify an apiID to update"), http.StatusBadRequest
}
case "DELETE":
case http.MethodDelete:
if apiID != "" {
log.Debug("Deleting API definition for: ", apiID)
obj, code = gw.handleDeleteAPI(apiID)
Expand Down
2 changes: 1 addition & 1 deletion gateway/api_loader.go
Expand Up @@ -908,7 +908,7 @@ func (gw *Gateway) loadApps(specs []*APISpec) {
for _, spec := range specs {
func() {
defer func() {
// recover from panic if one occured. Set err to nil otherwise.
// recover from panic if one occurred. Set err to nil otherwise.
if err := recover(); err != nil {
log.Errorf("Panic while loading an API: %v, panic: %v, stacktrace: %v", spec.APIDefinition, err, string(debug.Stack()))
}
Expand Down

0 comments on commit 52f3b3f

Please sign in to comment.