Skip to content

Commit

Permalink
Merging to release-5-lts: [TT-9628] Reset fields inside classic API d…
Browse files Browse the repository at this point in the history
…ef but removed from OAS (#5419)

[TT-9628] Reset fields inside classic API def but removed from OAS (#5419)

<details open>
<summary><a href="https://tyktech.atlassian.net/browse/TT-9628"
title="TT-9628" target="_blank">TT-9628</a></summary>
  <br />
  <table>
    <tr>
      <th>Summary</th>
<td>Accept CRUD operations of OAS APIs with DB stored API
definition</td>
    </tr>
    <tr>
      <th>Type</th>
      <td>
<img alt="Story"
src="https://tyktech.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10315?size=medium"
/>
        Story
      </td>
    </tr>
    <tr>
      <th>Status</th>
      <td>In Code Review</td>
    </tr>
    <tr>
      <th>Points</th>
      <td>N/A</td>
    </tr>
    <tr>
      <th>Labels</th>
<td><a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20Carnival%20ORDER%20BY%20created%20DESC"
title="Carnival">Carnival</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20customer_request%20ORDER%20BY%20created%20DESC"
title="customer_request">customer_request</a></td>
    </tr>
  </table>
</details>
<!--
  do not remove this marker as it will break jira-lint's functionality.
  added_by_jira_lint
-->

---

This PR introduces the ability to reset fields in the classic API
definition that have been populated when OAS removes corresponding
fields.
  • Loading branch information
buger authored Aug 21, 2023
1 parent 26c1a5f commit aa7ce33
Show file tree
Hide file tree
Showing 11 changed files with 523 additions and 67 deletions.
1 change: 1 addition & 0 deletions apidef/oas/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ func (o *OIDC) ExtractTo(api *apidef.APIDefinition) {
api.AuthConfigs["oidc"] = authConfig

api.OpenIDOptions.SegregateByClient = o.SegregateByClientId

api.OpenIDOptions.Providers = []apidef.OIDProviderConfig{}
for _, p := range o.Providers {
clientIDs := make(map[string]string)
Expand Down
90 changes: 70 additions & 20 deletions apidef/oas/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ func (m *Middleware) Fill(api apidef.APIDefinition) {

// ExtractTo extracts *Middleware into *apidef.APIDefinition.
func (m *Middleware) ExtractTo(api *apidef.APIDefinition) {
if m.Global != nil {
m.Global.ExtractTo(api)
if m.Global == nil {
m.Global = &Global{}
defer func() {
m.Global = nil
}()
}

m.Global.ExtractTo(api)
}

// Global holds configuration applies globally: CORS and caching.
Expand Down Expand Up @@ -134,33 +139,68 @@ func (g *Global) Fill(api apidef.APIDefinition) {

// ExtractTo extracts *Global into *apidef.APIDefinition.
func (g *Global) ExtractTo(api *apidef.APIDefinition) {
if g.PluginConfig != nil {
g.PluginConfig.ExtractTo(api)
if g.PluginConfig == nil {
g.PluginConfig = &PluginConfig{}
defer func() {
g.PluginConfig = nil
}()
}

if g.CORS != nil {
g.CORS.ExtractTo(&api.CORS)
g.PluginConfig.ExtractTo(api)

if g.CORS == nil {
g.CORS = &CORS{}
defer func() {
g.CORS = nil
}()
}

if g.PrePlugin != nil {
g.PrePlugin.ExtractTo(api)
g.CORS.ExtractTo(&api.CORS)

if g.PrePlugin == nil {
g.PrePlugin = &PrePlugin{}
defer func() {
g.PrePlugin = nil
}()
}

if g.PostAuthenticationPlugin != nil {
g.PostAuthenticationPlugin.ExtractTo(api)
g.PrePlugin.ExtractTo(api)

if g.PostAuthenticationPlugin == nil {
g.PostAuthenticationPlugin = &PostAuthenticationPlugin{}
defer func() {
g.PostAuthenticationPlugin = nil
}()
}

if g.PostPlugin != nil {
g.PostPlugin.ExtractTo(api)
g.PostAuthenticationPlugin.ExtractTo(api)

if g.PostPlugin == nil {
g.PostPlugin = &PostPlugin{}
defer func() {
g.PostPlugin = nil
}()
}

if g.Cache != nil {
g.Cache.ExtractTo(&api.CacheOptions)
g.PostPlugin.ExtractTo(api)

if g.Cache == nil {
g.Cache = &Cache{}
defer func() {
g.Cache = nil
}()
}

if g.ResponsePlugin != nil {
g.ResponsePlugin.ExtractTo(api)
g.Cache.ExtractTo(&api.CacheOptions)

if g.ResponsePlugin == nil {
g.ResponsePlugin = &ResponsePlugin{}
defer func() {
g.ResponsePlugin = nil
}()
}

g.ResponsePlugin.ExtractTo(api)
}

// PluginConfigData configures config data for custom plugins.
Expand Down Expand Up @@ -232,13 +272,23 @@ func (p *PluginConfig) Fill(api apidef.APIDefinition) {
func (p *PluginConfig) ExtractTo(api *apidef.APIDefinition) {
api.CustomMiddleware.Driver = p.Driver

if p.Bundle != nil {
p.Bundle.ExtractTo(api)
if p.Bundle == nil {
p.Bundle = &PluginBundle{}
defer func() {
p.Bundle = nil
}()
}

if p.Data != nil {
p.Data.ExtractTo(api)
p.Bundle.ExtractTo(api)

if p.Data == nil {
p.Data = &PluginConfigData{}
defer func() {
p.Data = nil
}()
}

p.Data.ExtractTo(api)
}

// PluginBundle holds configuration for custom plugins.
Expand Down
22 changes: 11 additions & 11 deletions apidef/oas/oas.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,21 @@ func (s *OAS) Fill(api apidef.APIDefinition) {

// ExtractTo extracts *OAS into *apidef.APIDefinition.
func (s *OAS) ExtractTo(api *apidef.APIDefinition) {
if s.GetTykExtension() != nil {
s.GetTykExtension().ExtractTo(api)
if s.GetTykExtension() == nil {
s.SetTykExtension(&XTykAPIGateway{})
defer func() {
delete(s.Extensions, ExtensionTykAPIGateway)
}()
}

s.extractSecurityTo(api)
s.GetTykExtension().ExtractTo(api)

ep := api.VersionData.Versions[Main].ExtendedPaths
s.extractPathsAndOperations(&ep)
s.extractSecurityTo(api)

api.VersionData.Versions = map[string]apidef.VersionInfo{
Main: {
UseExtendedPaths: true,
ExtendedPaths: ep,
},
}
vInfo := api.VersionData.Versions[Main]
vInfo.UseExtendedPaths = true
s.extractPathsAndOperations(&vInfo.ExtendedPaths)
api.VersionData.Versions[Main] = vInfo
}

// SetTykExtension populates our OAS schema extension inside *OAS.
Expand Down
212 changes: 212 additions & 0 deletions apidef/oas/oas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,218 @@ func TestOAS_ExtractTo_DontTouchExistingClassicFields(t *testing.T) {
assert.Len(t, api.VersionData.Versions[Main].ExtendedPaths.TransformHeader, 1)
}

func TestOAS_ExtractTo_ResetAPIDefinition(t *testing.T) {
var a apidef.APIDefinition
Fill(t, &a, 0)

var vInfo apidef.VersionInfo
Fill(t, &vInfo, 0)
a.VersionData.Versions = map[string]apidef.VersionInfo{
Main: vInfo,
}

var s OAS
s.ExtractTo(&a)

a.UseKeylessAccess = false
a.UpstreamCertificatesDisabled = false
a.CertificatePinningDisabled = false
a.Proxy.ServiceDiscovery.CacheDisabled = false
a.CustomMiddlewareBundleDisabled = false
a.DomainDisabled = false
a.ConfigDataDisabled = false
a.TagsDisabled = false
a.IsOAS = false

// deprecated fields
a.Auth = apidef.AuthConfig{}
a.VersionDefinition.StripPath = false
a.UseGoPluginAuth = false
a.EnableCoProcessAuth = false
a.JWTScopeToPolicyMapping = nil
a.JWTScopeClaimName = ""
a.VersionData.NotVersioned = false
vInfo = a.VersionData.Versions[""]
vInfo.Name = ""
vInfo.Expires = ""
vInfo.Paths.Ignored = nil
vInfo.Paths.WhiteList = nil
vInfo.Paths.BlackList = nil
vInfo.OverrideTarget = ""
vInfo.UseExtendedPaths = false
vInfo.ExtendedPaths.MockResponse = nil
vInfo.ExtendedPaths.Cached = nil
vInfo.ExtendedPaths.ValidateJSON = nil
a.VersionData.Versions[""] = vInfo

assert.Empty(t, a.Name)

noOASSupportFields := getNonEmptyFields(a, "APIDefinition")

expectedFields := []string{
"APIDefinition.ListenPort",
"APIDefinition.Protocol",
"APIDefinition.EnableProxyProtocol",
"APIDefinition.RequestSigning.IsEnabled",
"APIDefinition.RequestSigning.Secret",
"APIDefinition.RequestSigning.KeyId",
"APIDefinition.RequestSigning.Algorithm",
"APIDefinition.RequestSigning.HeaderList[0]",
"APIDefinition.RequestSigning.CertificateId",
"APIDefinition.RequestSigning.SignatureHeader",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQ[0].Filter",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQ[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQ[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQResponse[0].Filter",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQResponse[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformJQResponse[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformHeader[0].DeleteHeaders[0]",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformHeader[0].AddHeaders[0]",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformHeader[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformHeader[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformHeader[0].ActOnResponse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformResponseHeader[0].DeleteHeaders[0]",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformResponseHeader[0].AddHeaders[0]",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformResponseHeader[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformResponseHeader[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TransformResponseHeader[0].ActOnResponse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].ThresholdPercent",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].Samples",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].ReturnToServiceAfter",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.CircuitBreaker[0].DisableHalfOpenState",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].RewriteTo",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].On",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.HeaderMatches[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.HeaderMatches[0].Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.QueryValMatches[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.QueryValMatches[0].Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.PathPartMatches[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.PathPartMatches[0].Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.SessionMetaMatches[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.SessionMetaMatches[0].Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.RequestContextMatches[0].MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.RequestContextMatches[0].Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.PayloadMatches.MatchPattern",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].Options.PayloadMatches.Reverse",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.URLRewrite[0].Triggers[0].RewriteTo",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.SizeLimit[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.SizeLimit[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.SizeLimit[0].SizeLimit",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TrackEndpoints[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.TrackEndpoints[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.DoNotTrackEndpoints[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.DoNotTrackEndpoints[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.Internal[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.Internal[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.PersistGraphQL[0].Path",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.PersistGraphQL[0].Method",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.PersistGraphQL[0].Operation",
"APIDefinition.VersionData.Versions[0].ExtendedPaths.PersistGraphQL[0].Variables[0]",
"APIDefinition.VersionData.Versions[0].GlobalHeaders[0]",
"APIDefinition.VersionData.Versions[0].GlobalHeadersRemove[0]",
"APIDefinition.VersionData.Versions[0].GlobalResponseHeaders[0]",
"APIDefinition.VersionData.Versions[0].GlobalResponseHeadersRemove[0]",
"APIDefinition.VersionData.Versions[0].IgnoreEndpointCase",
"APIDefinition.VersionData.Versions[0].GlobalSizeLimit",
"APIDefinition.UptimeTests.CheckList[0].CheckURL",
"APIDefinition.UptimeTests.CheckList[0].Protocol",
"APIDefinition.UptimeTests.CheckList[0].Timeout",
"APIDefinition.UptimeTests.CheckList[0].EnableProxyProtocol",
"APIDefinition.UptimeTests.CheckList[0].Commands[0].Name",
"APIDefinition.UptimeTests.CheckList[0].Commands[0].Message",
"APIDefinition.UptimeTests.CheckList[0].Method",
"APIDefinition.UptimeTests.CheckList[0].Headers[0]",
"APIDefinition.UptimeTests.CheckList[0].Body",
"APIDefinition.UptimeTests.Config.ExpireUptimeAnalyticsAfter",
"APIDefinition.UptimeTests.Config.ServiceDiscovery.CacheDisabled",
"APIDefinition.UptimeTests.Config.RecheckWait",
"APIDefinition.Proxy.PreserveHostHeader",
"APIDefinition.Proxy.DisableStripSlash",
"APIDefinition.Proxy.EnableLoadBalancing",
"APIDefinition.Proxy.Targets[0]",
"APIDefinition.Proxy.CheckHostAgainstUptimeTests",
"APIDefinition.Proxy.Transport.SSLInsecureSkipVerify",
"APIDefinition.Proxy.Transport.SSLCipherSuites[0]",
"APIDefinition.Proxy.Transport.SSLMinVersion",
"APIDefinition.Proxy.Transport.SSLMaxVersion",
"APIDefinition.Proxy.Transport.SSLForceCommonNameCheck",
"APIDefinition.Proxy.Transport.ProxyURL",
"APIDefinition.DisableRateLimit",
"APIDefinition.DisableQuota",
"APIDefinition.SessionLifetimeRespectsKeyExpiration",
"APIDefinition.SessionLifetime",
"APIDefinition.AuthProvider.Name",
"APIDefinition.AuthProvider.StorageEngine",
"APIDefinition.AuthProvider.Meta[0]",
"APIDefinition.SessionProvider.Name",
"APIDefinition.SessionProvider.StorageEngine",
"APIDefinition.SessionProvider.Meta[0]",
"APIDefinition.EventHandlers.Events[0]",
"APIDefinition.EnableBatchRequestSupport",
"APIDefinition.EnableIpWhiteListing",
"APIDefinition.AllowedIPs[0]",
"APIDefinition.EnableIpBlacklisting",
"APIDefinition.BlacklistedIPs[0]",
"APIDefinition.DontSetQuotasOnCreate",
"APIDefinition.ExpireAnalyticsAfter",
"APIDefinition.ResponseProcessors[0].Name",
"APIDefinition.ResponseProcessors[0].Options",
"APIDefinition.Certificates[0]",
"APIDefinition.DoNotTrack",
"APIDefinition.EnableContextVars",
"APIDefinition.TagHeaders[0]",
"APIDefinition.GlobalRateLimit.Rate",
"APIDefinition.GlobalRateLimit.Per",
"APIDefinition.EnableDetailedRecording",
"APIDefinition.GraphQL.Enabled",
"APIDefinition.GraphQL.ExecutionMode",
"APIDefinition.GraphQL.Version",
"APIDefinition.GraphQL.Schema",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].TypeName",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].FieldName",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].Mapping.Disabled",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].Mapping.Path",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].DataSource.Name",
"APIDefinition.GraphQL.TypeFieldConfigurations[0].DataSource.Config[0]",
"APIDefinition.GraphQL.GraphQLPlayground.Enabled",
"APIDefinition.GraphQL.GraphQLPlayground.Path",
"APIDefinition.GraphQL.Engine.FieldConfigs[0].TypeName",
"APIDefinition.GraphQL.Engine.FieldConfigs[0].FieldName",
"APIDefinition.GraphQL.Engine.FieldConfigs[0].DisableDefaultMapping",
"APIDefinition.GraphQL.Engine.FieldConfigs[0].Path[0]",
"APIDefinition.GraphQL.Engine.DataSources[0].Kind",
"APIDefinition.GraphQL.Engine.DataSources[0].Name",
"APIDefinition.GraphQL.Engine.DataSources[0].Internal",
"APIDefinition.GraphQL.Engine.DataSources[0].RootFields[0].Type",
"APIDefinition.GraphQL.Engine.DataSources[0].RootFields[0].Fields[0]",
"APIDefinition.GraphQL.Engine.DataSources[0].Config[0]",
"APIDefinition.GraphQL.Proxy.AuthHeaders[0]",
"APIDefinition.GraphQL.Proxy.SubscriptionType",
"APIDefinition.GraphQL.Proxy.RequestHeaders[0]",
"APIDefinition.GraphQL.Proxy.UseResponseExtensions.OnErrorForwarding",
"APIDefinition.GraphQL.Subgraph.SDL",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].APIID",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].Name",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].URL",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].SDL",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].Headers[0]",
"APIDefinition.GraphQL.Supergraph.Subgraphs[0].SubscriptionType",
"APIDefinition.GraphQL.Supergraph.MergedSDL",
"APIDefinition.GraphQL.Supergraph.GlobalHeaders[0]",
"APIDefinition.GraphQL.Supergraph.DisableQueryBatching",
"APIDefinition.AnalyticsPlugin.Enabled",
"APIDefinition.AnalyticsPlugin.PluginPath",
"APIDefinition.AnalyticsPlugin.FuncName",
}

assert.Equal(t, expectedFields, noOASSupportFields)
}

func TestOAS_AddServers(t *testing.T) {
t.Parallel()
type fields struct {
Expand Down
Loading

0 comments on commit aa7ce33

Please sign in to comment.