Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tools/cli/internal/openapi/filter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +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 updates the x-sunset and x-xgen-version extensions to a date string](../internal/openapi/filter/extension.go?plain=1#L24)
[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)
[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)
Expand Down
113 changes: 108 additions & 5 deletions tools/cli/internal/openapi/filter/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,19 @@ import (
"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
// Filter: ExtensionFilter is a filter that deletes the x-xgen-ipa-exception extensions, 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 ExtensionFilter struct {
oas *openapi3.T
metadata *Metadata
}

const (
sunsetExtension = "x-sunset"
xGenExtension = "x-xgen-version"
format = "2006-01-02T15:04:05Z07:00"
sunsetExtension = "x-sunset"
xGenExtension = "x-xgen-version"
ipaExceptionExtension = "x-xgen-IPA-exception"
format = "2006-01-02T15:04:05Z07:00"
)

func (f *ExtensionFilter) Apply() error {
Expand All @@ -42,27 +43,52 @@ func (f *ExtensionFilter) Apply() error {
continue
}
updateExtensionToDateString(pathItem.Extensions)
deleteIpaExceptionExtension(pathItem.Extensions)

for _, operation := range pathItem.Operations() {
if operation == nil {
continue
}

updateExtensionToDateString(operation.Extensions)
deleteIpaExceptionExtension(operation.Extensions)

for _, parameter := range operation.Parameters {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐻 with me this is a bit messy but need to look at the code in an editor to help you a bit

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup it's a bit messy, happy to get feedback on this one 😅

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to break the code into separate functions, with each function handling a specific component type? It might make the code easier to follow and maintain

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yelizhenden-mdb 💯 yes that was one approach but I think filtering in general needs some love
I haven't really have the time to go deeper here since I found other stuff in the repo that needed fixing like some improved linting but you can split this in functions and leverage the fact that go encourage argument modification, is quite common in go to name an argument out to flag it will be modified by the function

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split some parts to more functions, let me know if it's a bit better.

is quite common in go to name an argument out to flag it will be modified by the function

Not sure what you mean here, unless you mean naming the parameter to out

if parameter.Value == nil || parameter.Value.Schema == nil {
continue
}
deleteIpaExceptionExtension(parameter.Value.Schema.Extensions)
if parameter.Value.Schema.Value == nil {
continue
}
deleteIpaExceptionExtension(parameter.Value.Schema.Value.Extensions)
}

latestVersionMatch := apiversion.FindLatestContentVersionMatched(operation, f.metadata.targetVersion)

if operation.RequestBody != nil {
deleteIpaExceptionExtension(operation.RequestBody.Extensions)
_, contentsInVersion := getVersionsInContentType(operation.RequestBody.Value.Content)
for _, content := range contentsInVersion {
deleteIpaExceptionExtension(content.Extensions)
updateExtensionsForSchema(content.Schema)
}
}

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
Expand All @@ -80,6 +106,12 @@ func (f *ExtensionFilter) Apply() error {
f.deleteSunsetIfDeprecatedByHiddenVersions(latestVersionMatch, request.Value.Content)
}
}
if f.oas.Tags != nil {
updateExtensionsForTags(&f.oas.Tags)
}
if f.oas.Components != nil {
updateExtensionsForComponents(f.oas.Components)
}
return nil
}

Expand All @@ -100,6 +132,77 @@ func updateExtensionToDateString(extensions map[string]any) {
}
}

func updateExtensionsForComponents(components *openapi3.Components) {
for _, schema := range components.Schemas {
updateExtensionsForSchema(schema)
}
for _, parameter := range components.Parameters {
if parameter != nil {
deleteIpaExceptionExtension(parameter.Extensions)
}
}
}

func updateExtensionsForTags(tags *openapi3.Tags) {
for _, tag := range *tags {
if tag != nil {
deleteIpaExceptionExtension(tag.Extensions)
}
}
}

func updateExtensionsForSchema(schema *openapi3.SchemaRef) {
if schema != nil {
deleteIpaExceptionExtension(schema.Extensions)
}
if schema.Value != nil {
deleteIpaExceptionExtension(schema.Value.Extensions)
for _, allOf := range schema.Value.AllOf {
if allOf.Value == nil {
continue
}
for _, property := range allOf.Value.Properties {
if property.Value != nil {
deleteIpaExceptionExtension(property.Value.Extensions)
}
}
}
for _, anyOf := range schema.Value.AnyOf {
if anyOf.Value == nil {
continue
}
for _, property := range anyOf.Value.Properties {
if property.Value != nil {
deleteIpaExceptionExtension(property.Value.Extensions)
}
}
}
for _, oneOf := range schema.Value.OneOf {
if oneOf.Value == nil {
continue
}
for _, property := range oneOf.Value.Properties {
if property.Value != nil {
deleteIpaExceptionExtension(property.Value.Extensions)
}
}
}
for _, property := range schema.Value.Properties {
if property.Value != nil {
deleteIpaExceptionExtension(property.Value.Extensions)
}
}
}
}

func deleteIpaExceptionExtension(extensions map[string]any) {
if extensions == nil || extensions[ipaExceptionExtension] == nil {
return
}

delete(extensions, ipaExceptionExtension)
}

func (f *ExtensionFilter) updateToDateString(content openapi3.Content) {
for _, mediaType := range content {
if mediaType.Extensions == nil {
Expand Down
Loading
Loading