From a73bf489e9dcb95f7c0b9f905a31dec1efe9c53e Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Wed, 5 Mar 2025 18:45:58 +0000 Subject: [PATCH 1/3] chore: decouple extension filters from versioning extension filters --- tools/cli/internal/openapi/filter/README.md | 6 +- .../cli/internal/openapi/filter/extension.go | 94 +--------- .../internal/openapi/filter/extension_test.go | 121 ------------- tools/cli/internal/openapi/filter/filter.go | 1 + .../internal/openapi/filter/hidden_envs.go | 13 -- .../openapi/filter/versioning_extension.go | 166 ++++++++++++++++++ .../filter/versioning_extension_test.go | 146 +++++++++++++++ 7 files changed, 316 insertions(+), 231 deletions(-) create mode 100644 tools/cli/internal/openapi/filter/versioning_extension.go create mode 100644 tools/cli/internal/openapi/filter/versioning_extension_test.go diff --git a/tools/cli/internal/openapi/filter/README.md b/tools/cli/internal/openapi/filter/README.md index 3981b6c1a0..a98d2964b9 100644 --- a/tools/cli/internal/openapi/filter/README.md +++ b/tools/cli/internal/openapi/filter/README.md @@ -8,9 +8,7 @@ The Atlas Admin API OpenAPI specifications are used not only to document REST en - Filtering per version, so that only the endpoints that are available in that version are shown. ## What filters are available? ### List of filters -[ExtensionFilter is a filter that deletes the x-xgen-ipa-exception extensions, updates the x-sunset and x-xgen-version](../internal/openapi/filter/extension.go?plain=1#L24) +[ExtensionFilter is a filter that updates the x-sunset and x-xgen-version extensions to a date string](../internal/openapi/filter/extension.go?plain=1#L25) [HiddenEnvsFilter is a filter that removes paths, operations,](../internal/openapi/filter/hidden_envs.go?plain=1#L28) -[InfoFilter is a filter that modifies the Info object in the OpenAPI spec.](../internal/openapi/filter/info.go?plain=1#L23) [OperationsFilter is a filter that removes the x-xgen-owner-team extension from operations](../internal/openapi/filter/operations.go?plain=1#L20) -[TagsFilter removes tags that are not used in the operations.](../internal/openapi/filter/tags.go?plain=1#L22) -[VersioningFilter is a filter that modifies the OpenAPI spec by removing operations and responses](../internal/openapi/filter/versioning.go?plain=1#L24) +[VersioningFilter is a filter that modifies the OpenAPI spec by removing operations and responses](../internal/openapi/filter/versioning.go?plain=1#L25) diff --git a/tools/cli/internal/openapi/filter/extension.go b/tools/cli/internal/openapi/filter/extension.go index e55a137624..d04d71df66 100644 --- a/tools/cli/internal/openapi/filter/extension.go +++ b/tools/cli/internal/openapi/filter/extension.go @@ -15,24 +15,16 @@ package filter import ( - "log" - "time" - "github.com/getkin/kin-openapi/openapi3" - "github.com/mongodb/openapi/tools/cli/internal/apiversion" ) -// Filter: ExtensionFilter is a filter that updates the x-sunset and x-xgen-version extensions to a date string -// and deletes the x-sunset extension if the latest matched version is deprecated by hidden versions -// for the target environment. +// Filter: ExtensionFilter is a filter that removes the x-xgen-IPA-exception extension from the OpenAPI spec. type ExtensionFilter struct { oas *openapi3.T metadata *Metadata } const ( - sunsetExtension = "x-sunset" - xGenExtension = "x-xgen-version" ipaExceptionExtension = "x-xgen-IPA-exception" format = "2006-01-02T15:04:05Z07:00" ) @@ -42,7 +34,6 @@ func (f *ExtensionFilter) Apply() error { if pathItem == nil { continue } - updateExtensionToDateString(pathItem.Extensions) deleteIpaExceptionExtension(pathItem.Extensions) for _, operation := range pathItem.Operations() { @@ -50,7 +41,6 @@ func (f *ExtensionFilter) Apply() error { continue } - updateExtensionToDateString(operation.Extensions) deleteIpaExceptionExtension(operation.Extensions) if operation.Parameters != nil { @@ -59,37 +49,28 @@ func (f *ExtensionFilter) Apply() error { updateExtensionsForRequestBody(operation.RequestBody) - latestVersionMatch := apiversion.FindLatestContentVersionMatched(operation, f.metadata.targetVersion) - for _, response := range operation.Responses.Map() { if response == nil { continue } - updateExtensionToDateString(response.Extensions) deleteIpaExceptionExtension(response.Extensions) if response.Value == nil { continue } - updateExtensionToDateString(response.Value.Extensions) deleteIpaExceptionExtension(response.Value.Extensions) if response.Value.Content == nil { continue } - - f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, response.Value.Content) - updateToDateString(response.Value.Content) } request := operation.RequestBody if request == nil || request.Value == nil || request.Value.Content == nil { continue } - updateToDateString(request.Value.Content) - f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, request.Value.Content) } } if f.oas.Tags != nil { @@ -196,76 +177,3 @@ func deleteIpaExceptionExtension(extensions map[string]any) { delete(extensions, ipaExceptionExtension) } - -func updateExtensionToDateString(extensions map[string]any) { - if extensions == nil { - return - } - - for k, v := range extensions { - if k != sunsetExtension && k != xGenExtension { - continue - } - date, err := time.Parse(format, v.(string)) - if err != nil { - continue - } - extensions[k] = date.Format("2006-01-02") - } -} - -func updateToDateString(content openapi3.Content) { - for _, mediaType := range content { - if mediaType.Extensions == nil { - continue - } - - updateExtensionToDateString(mediaType.Extensions) - } -} - -// deleteSunsetIfDeprecatedByHiddenVersions deletes the sunset extension if the latest matched version is deprecated by hidden versions. -func (f *ExtensionFilter) deleteSunsetIfDeprecatedByHiddenVersions(latestMatchedVersion *apiversion.APIVersion, content openapi3.Content) { - versions, versionToContentType := getVersionsInContentType(content) - - deprecatedByHiddenVersions := make([]*apiversion.APIVersion, 0) - deprecatedByVersions := make([]*apiversion.APIVersion, 0) - - for _, v := range versions { - if v.GreaterThan(latestMatchedVersion) { - if value, ok := versionToContentType[v.String()]; ok { - if isContentTypeHiddenForEnv(value, f.metadata.targetEnv) { - deprecatedByHiddenVersions = append(deprecatedByHiddenVersions, v) - continue - } - deprecatedByVersions = append(deprecatedByVersions, v) - } - } - } - - // If the exact requested version is marked for sunset for a list of hidden versions - if value, ok := versionToContentType[latestMatchedVersion.String()]; ok { - if len(deprecatedByHiddenVersions) > 0 && len(deprecatedByVersions) == 0 && value.Extensions != nil { - delete(value.Extensions, sunsetExtension) - } - } -} - -func getVersionsInContentType(content map[string]*openapi3.MediaType) ( - versions []*apiversion.APIVersion, contentsInVersion map[string]*openapi3.MediaType) { - contentsInVersion = make(map[string]*openapi3.MediaType) - versionsInContentType := make(map[string]*apiversion.APIVersion) - - for contentType, contentValue := range content { - v, err := apiversion.New(apiversion.WithFullContent(contentType, contentValue)) - if err != nil { - log.Printf("Ignoring invalid content type: %s", contentType) - continue - } - versions = append(versions, v) - versionsInContentType[v.String()] = v - contentsInVersion[v.String()] = content[contentType] - } - - return versions, contentsInVersion -} diff --git a/tools/cli/internal/openapi/filter/extension_test.go b/tools/cli/internal/openapi/filter/extension_test.go index 1236be09f9..fd7fc13556 100644 --- a/tools/cli/internal/openapi/filter/extension_test.go +++ b/tools/cli/internal/openapi/filter/extension_test.go @@ -24,59 +24,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestXSunsetFilter_removeSunset(t *testing.T) { - tests := []struct { - name string - oas *openapi3.T - version string - sunsetDate string - }{ - { - name: "sunset 2023-01-01", - oas: getOasSunset(), - version: "2023-01-01", - sunsetDate: "2024-05-30", - }, - { - name: "sunset 2024-05-30", - oas: getOasSunset(), - version: "2024-05-30", - sunsetDate: "", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - version, err := apiversion.New(apiversion.WithVersion(tt.version)) - require.NoError(t, err) - oas := tt.oas - - filter := &ExtensionFilter{ - oas: oas, - metadata: &Metadata{targetVersion: version, targetEnv: "dev"}, - } - - contentKey := fmt.Sprintf("application/vnd.atlas.%s+json", tt.version) - require.NoError(t, filter.Apply()) - assert.NotNil(t, oas.Paths.Find("/path").Get) - assert.NotEmpty(t, oas.Paths.Find("/path").Get.Responses) - assert.NotNil(t, oas.Paths.Find("/path").Get.Responses.Map()["200"]) - - versionExtension := oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions[xGenExtension] - assert.Equal(t, tt.version, versionExtension) - - if tt.sunsetDate == "" { - assert.Empty(t, oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions[sunsetExtension]) - return - } - - assert.NotNil(t, oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey)) - contentExtensions := oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions - assert.Contains(t, contentExtensions, sunsetExtension) - assert.Equal(t, tt.sunsetDate, contentExtensions[sunsetExtension]) - }) - } -} - func TestExtensionFilter_removeIpaException(t *testing.T) { oas := getOasIpaExceptions() version, err := apiversion.New(apiversion.WithVersion("2023-01-01")) @@ -196,74 +143,6 @@ func TestExtensionFilter_removeIpaException(t *testing.T) { } } -func getOasSunset() *openapi3.T { - oas := &openapi3.T{} - oas.Paths = &openapi3.Paths{} - - operation := &openapi3.Operation{ - Responses: &openapi3.Responses{}, - } - - operation.Responses.Set("200", &openapi3.ResponseRef{ - Value: &openapi3.Response{ - Content: map[string]*openapi3.MediaType{ - "application/vnd.atlas.2023-01-01+json": { - Schema: &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Description: "description", - }, - }, - Extensions: map[string]any{ - "x-sunset": "2024-05-30T00:00:00Z", - xGenExtension: "2023-01-01T00:00:00Z", - }, - }, - "application/vnd.atlas.2024-02-30+json": { - Schema: &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Description: "description", - }, - }, - Extensions: map[string]any{ - "x-sunset": "2024-04-10", - xGenExtension: "2024-02-30T00:00:00Z", - }, - }, - "application/vnd.atlas.2025-01-01+json": { - Schema: &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Description: "description", - }, - Extensions: map[string]any{ - "x-sunset": "2025-01-01T00:00:00Z", - xGenExtension: "2025-01-01", - }, - }, - Extensions: map[string]any{ - hiddenEnvsExtension: map[string]any{ - "envs": "dev,qa,prod,stage", - }, - }, - }, - "application/vnd.atlas.2024-05-30+json": { - Schema: &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Description: "description", - }, - }, - Extensions: map[string]any{ - "x-sunset": "2025-01-01T00:00:00Z", - xGenExtension: "2024-05-30", - }, - }, - }, - }, - }) - - oas.Paths.Set("/path", &openapi3.PathItem{Get: operation}) - return oas -} - func getOasIpaExceptions() *openapi3.T { extension := map[string]any{ ipaExceptionExtension: map[string]string{"IPA-104-resource-has-GET": "reason"}, diff --git a/tools/cli/internal/openapi/filter/filter.go b/tools/cli/internal/openapi/filter/filter.go index 158be49b1e..03a7b8955e 100644 --- a/tools/cli/internal/openapi/filter/filter.go +++ b/tools/cli/internal/openapi/filter/filter.go @@ -50,6 +50,7 @@ func validateMetadata(metadata *Metadata) error { func DefaultFilters(oas *openapi3.T, metadata *Metadata) []Filter { return []Filter{ &ExtensionFilter{oas: oas, metadata: metadata}, + &VersioningExtensionFilter{oas: oas, metadata: metadata}, &VersioningFilter{oas: oas, metadata: metadata}, &InfoFilter{oas: oas, metadata: metadata}, &HiddenEnvsFilter{oas: oas, metadata: metadata}, diff --git a/tools/cli/internal/openapi/filter/hidden_envs.go b/tools/cli/internal/openapi/filter/hidden_envs.go index 23b6d33469..3c6bcfa494 100644 --- a/tools/cli/internal/openapi/filter/hidden_envs.go +++ b/tools/cli/internal/openapi/filter/hidden_envs.go @@ -165,19 +165,6 @@ func (f *HiddenEnvsFilter) isResponseHiddenForEnv(response *openapi3.ResponseRef return false } -func isContentTypeHiddenForEnv(contentType *openapi3.MediaType, targetEnv string) bool { - if contentType == nil { - return false - } - - if extension, ok := contentType.Extensions[hiddenEnvsExtension]; ok { - log.Printf("Found x-hidden-envs: K: %q, V: %q", hiddenEnvsExtension, extension) - return isHiddenExtensionEqualToTargetEnv(extension, targetEnv) - } - - return false -} - func (f *HiddenEnvsFilter) isRequestBodyHiddenForEnv(requestBody *openapi3.RequestBodyRef) bool { if requestBody == nil { return false diff --git a/tools/cli/internal/openapi/filter/versioning_extension.go b/tools/cli/internal/openapi/filter/versioning_extension.go new file mode 100644 index 0000000000..17b8cbf038 --- /dev/null +++ b/tools/cli/internal/openapi/filter/versioning_extension.go @@ -0,0 +1,166 @@ +// Copyright 2024 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package filter + +import ( + "log" + "time" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/mongodb/openapi/tools/cli/internal/apiversion" +) + +// Filter: VersioningExtensionFilter is a filter that updates the x-sunset and x-xgen-version extensions to a date string +// and deletes the x-sunset extension if the latest matched version is deprecated by hidden versions +// for the target environment. +type VersioningExtensionFilter struct { + oas *openapi3.T + metadata *Metadata +} + +const ( + sunsetExtension = "x-sunset" + xGenExtension = "x-xgen-version" +) + +func (f *VersioningExtensionFilter) Apply() error { + for _, pathItem := range f.oas.Paths.Map() { + if pathItem == nil { + continue + } + + updateExtensionToDateString(pathItem.Extensions) + + for _, operation := range pathItem.Operations() { + if operation == nil { + continue + } + + updateExtensionToDateString(operation.Extensions) + + latestVersionMatch := apiversion.FindLatestContentVersionMatched(operation, f.metadata.targetVersion) + + for _, response := range operation.Responses.Map() { + if response == nil { + continue + } + + updateExtensionToDateString(response.Extensions) + + if response.Value == nil { + continue + } + + updateExtensionToDateString(response.Value.Extensions) + if response.Value.Content == nil { + continue + } + + updateToDateString(response.Value.Content) + f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, response.Value.Content) + } + + request := operation.RequestBody + if request == nil || request.Value == nil || request.Value.Content == nil { + continue + } + updateToDateString(request.Value.Content) + f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, request.Value.Content) + } + } + + return nil +} + +// deleteSunsetIfDeprecatedByHiddenVersions deletes the sunset extension if the latest matched version is deprecated by hidden versions. +func (f *VersioningExtensionFilter) deleteSunsetIfDeprecatedByHiddenVersions(latestMatchedVersion *apiversion.APIVersion, content openapi3.Content) { + versions, versionToContentType := getVersionsInContentType(content) + + deprecatedByHiddenVersions := make([]*apiversion.APIVersion, 0) + deprecatedByVersions := make([]*apiversion.APIVersion, 0) + + for _, v := range versions { + if v.GreaterThan(latestMatchedVersion) { + if value, ok := versionToContentType[v.String()]; ok { + if isContentTypeHiddenForEnv(value, f.metadata.targetEnv) { + deprecatedByHiddenVersions = append(deprecatedByHiddenVersions, v) + continue + } + deprecatedByVersions = append(deprecatedByVersions, v) + } + } + } +} + +// isContentTypeHiddenForEnv returns true if the content type is hidden for the target environment. +func isContentTypeHiddenForEnv(contentType *openapi3.MediaType, targetEnv string) bool { + if contentType == nil { + return false + } + + if extension, ok := contentType.Extensions[hiddenEnvsExtension]; ok { + log.Printf("Found x-hidden-envs: K: %q, V: %q", hiddenEnvsExtension, extension) + return isHiddenExtensionEqualToTargetEnv(extension, targetEnv) + } + + return false +} + +// getVersionsInContentType returns a list of versions and a map of versions to content types. +func getVersionsInContentType(content map[string]*openapi3.MediaType) ( + versions []*apiversion.APIVersion, contentsInVersion map[string]*openapi3.MediaType) { + contentsInVersion = make(map[string]*openapi3.MediaType) + versionsInContentType := make(map[string]*apiversion.APIVersion) + + for contentType, contentValue := range content { + v, err := apiversion.New(apiversion.WithFullContent(contentType, contentValue)) + if err != nil { + log.Printf("Ignoring invalid content type: %s", contentType) + continue + } + versions = append(versions, v) + versionsInContentType[v.String()] = v + contentsInVersion[v.String()] = content[contentType] + } + + return versions, contentsInVersion +} + +func updateExtensionToDateString(extensions map[string]any) { + if extensions == nil { + return + } + + for k, v := range extensions { + if k != sunsetExtension && k != xGenExtension { + continue + } + date, err := time.Parse(format, v.(string)) + if err != nil { + continue + } + extensions[k] = date.Format("2006-01-02") + } +} + +func updateToDateString(content openapi3.Content) { + for _, mediaType := range content { + if mediaType.Extensions == nil { + continue + } + + updateExtensionToDateString(mediaType.Extensions) + } +} diff --git a/tools/cli/internal/openapi/filter/versioning_extension_test.go b/tools/cli/internal/openapi/filter/versioning_extension_test.go new file mode 100644 index 0000000000..bbd1d2ce2a --- /dev/null +++ b/tools/cli/internal/openapi/filter/versioning_extension_test.go @@ -0,0 +1,146 @@ +// Copyright 2024 MongoDB Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package filter + +import ( + "fmt" + "testing" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/mongodb/openapi/tools/cli/internal/apiversion" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVersioningExtensionFilter_removeSunset(t *testing.T) { + tests := []struct { + name string + oas *openapi3.T + version string + sunsetDate string + }{ + { + name: "sunset 2023-01-01", + oas: getOasSunset(), + version: "2023-01-01", + sunsetDate: "2024-05-30", + }, + { + name: "sunset 2024-05-30", + oas: getOasSunset(), + version: "2024-05-30", + sunsetDate: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + version, err := apiversion.New(apiversion.WithVersion(tt.version)) + require.NoError(t, err) + oas := tt.oas + + filter := &VersioningExtensionFilter{ + oas: oas, + metadata: &Metadata{targetVersion: version, targetEnv: "dev"}, + } + + contentKey := fmt.Sprintf("application/vnd.atlas.%s+json", tt.version) + require.NoError(t, filter.Apply()) + assert.NotNil(t, oas.Paths.Find("/path").Get) + assert.NotEmpty(t, oas.Paths.Find("/path").Get.Responses) + assert.NotNil(t, oas.Paths.Find("/path").Get.Responses.Map()["200"]) + + versionExtension := oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions[xGenExtension] + assert.Equal(t, tt.version, versionExtension) + + if tt.sunsetDate == "" { + assert.Empty(t, oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions[sunsetExtension]) + return + } + + assert.NotNil(t, oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey)) + contentExtensions := oas.Paths.Find("/path").Get.Responses.Map()["200"].Value.Content.Get(contentKey).Extensions + assert.Contains(t, contentExtensions, sunsetExtension) + assert.Equal(t, tt.sunsetDate, contentExtensions[sunsetExtension]) + }) + } +} + +func getOasSunset() *openapi3.T { + oas := &openapi3.T{} + oas.Paths = &openapi3.Paths{} + + operation := &openapi3.Operation{ + Responses: &openapi3.Responses{}, + } + + operation.Responses.Set("200", &openapi3.ResponseRef{ + Value: &openapi3.Response{ + Content: map[string]*openapi3.MediaType{ + "application/vnd.atlas.2023-01-01+json": { + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Description: "description", + }, + }, + Extensions: map[string]any{ + "x-sunset": "2024-05-30T00:00:00Z", + xGenExtension: "2023-01-01T00:00:00Z", + }, + }, + "application/vnd.atlas.2024-02-30+json": { + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Description: "description", + }, + }, + Extensions: map[string]any{ + "x-sunset": "2024-04-10", + xGenExtension: "2024-02-30T00:00:00Z", + }, + }, + "application/vnd.atlas.2025-01-01+json": { + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Description: "description", + }, + Extensions: map[string]any{ + "x-sunset": "2025-01-01T00:00:00Z", + xGenExtension: "2025-01-01", + }, + }, + Extensions: map[string]any{ + hiddenEnvsExtension: map[string]any{ + "envs": "dev,qa,prod,stage", + }, + }, + }, + "application/vnd.atlas.2024-05-30+json": { + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Description: "description", + }, + }, + Extensions: map[string]any{ + "x-sunset": "2025-01-01T00:00:00Z", + xGenExtension: "2024-05-30", + }, + }, + }, + }, + }) + + oas.Paths.Set("/path", &openapi3.PathItem{Get: operation}) + return oas +} From 8dc841be79ca811b918472ae38b52190b9a16a04 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 6 Mar 2025 10:40:13 +0000 Subject: [PATCH 2/3] Update --- .../internal/openapi/filter/hidden_envs.go | 14 ++++++++++++++ .../openapi/filter/versioning_extension.go | 19 ++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/tools/cli/internal/openapi/filter/hidden_envs.go b/tools/cli/internal/openapi/filter/hidden_envs.go index 3c6bcfa494..b053bc837e 100644 --- a/tools/cli/internal/openapi/filter/hidden_envs.go +++ b/tools/cli/internal/openapi/filter/hidden_envs.go @@ -195,3 +195,17 @@ func isHiddenExtensionEqualToTargetEnv(extension any, target string) bool { } return false } + +// isContentTypeHiddenForEnv returns true if the content type is hidden for the target environment. +func isContentTypeHiddenForEnv(contentType *openapi3.MediaType, targetEnv string) bool { + if contentType == nil { + return false + } + + if extension, ok := contentType.Extensions[hiddenEnvsExtension]; ok { + log.Printf("Found x-hidden-envs: K: %q, V: %q", hiddenEnvsExtension, extension) + return isHiddenExtensionEqualToTargetEnv(extension, targetEnv) + } + + return false +} diff --git a/tools/cli/internal/openapi/filter/versioning_extension.go b/tools/cli/internal/openapi/filter/versioning_extension.go index 17b8cbf038..d6597afa04 100644 --- a/tools/cli/internal/openapi/filter/versioning_extension.go +++ b/tools/cli/internal/openapi/filter/versioning_extension.go @@ -68,8 +68,8 @@ func (f *VersioningExtensionFilter) Apply() error { continue } - updateToDateString(response.Value.Content) f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, response.Value.Content) + updateToDateString(response.Value.Content) } request := operation.RequestBody @@ -102,20 +102,13 @@ func (f *VersioningExtensionFilter) deleteSunsetIfDeprecatedByHiddenVersions(lat } } } -} -// isContentTypeHiddenForEnv returns true if the content type is hidden for the target environment. -func isContentTypeHiddenForEnv(contentType *openapi3.MediaType, targetEnv string) bool { - if contentType == nil { - return false - } - - if extension, ok := contentType.Extensions[hiddenEnvsExtension]; ok { - log.Printf("Found x-hidden-envs: K: %q, V: %q", hiddenEnvsExtension, extension) - return isHiddenExtensionEqualToTargetEnv(extension, targetEnv) + // If the exact requested version is marked for sunset for a list of hidden versions + if value, ok := versionToContentType[latestMatchedVersion.String()]; ok { + if len(deprecatedByHiddenVersions) > 0 && len(deprecatedByVersions) == 0 && value.Extensions != nil { + delete(value.Extensions, sunsetExtension) + } } - - return false } // getVersionsInContentType returns a list of versions and a map of versions to content types. From 043c7be70a28e4261f15624465c93722067c24d4 Mon Sep 17 00:00:00 2001 From: Bianca Lisle Date: Thu, 6 Mar 2025 10:41:44 +0000 Subject: [PATCH 3/3] update --- tools/cli/internal/openapi/filter/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/cli/internal/openapi/filter/README.md b/tools/cli/internal/openapi/filter/README.md index a98d2964b9..f42557ac96 100644 --- a/tools/cli/internal/openapi/filter/README.md +++ b/tools/cli/internal/openapi/filter/README.md @@ -8,7 +8,8 @@ The Atlas Admin API OpenAPI specifications are used not only to document REST en - Filtering per version, so that only the endpoints that are available in that version are shown. ## What filters are available? ### List of filters -[ExtensionFilter is a filter that updates the x-sunset and x-xgen-version extensions to a date string](../internal/openapi/filter/extension.go?plain=1#L25) +[ExtensionFilter is a filter that removes the x-xgen-IPA-exception extension from the OpenAPI spec.](../internal/openapi/filter/extension.go?plain=1#L21) [HiddenEnvsFilter is a filter that removes paths, operations,](../internal/openapi/filter/hidden_envs.go?plain=1#L28) [OperationsFilter is a filter that removes the x-xgen-owner-team extension from operations](../internal/openapi/filter/operations.go?plain=1#L20) +[VersioningExtensionFilter is a filter that updates the x-sunset and x-xgen-version extensions to a date string](../internal/openapi/filter/versioning_extension.go?plain=1#L25) [VersioningFilter is a filter that modifies the OpenAPI spec by removing operations and responses](../internal/openapi/filter/versioning.go?plain=1#L25)