Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SALTO-7151: Fix "important values" generation for Swagger types #7104

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

Nurdok
Copy link
Contributor

@Nurdok Nurdok commented Jan 14, 2025

Replace me with a description of the changes in this PR


Additional context for reviewer


Release Notes:

  • Fixed important values generation for Swagger types in the new infra

User Notifications:
None

@Nurdok Nurdok changed the title SALTO-7151: Fix important values generation for Swagger types SALTO-7151: Fix "important values" generation for Swagger types Jan 14, 2025
@coveralls
Copy link

Coverage Status

coverage: 93.649% (-0.01%) from 93.661%
when pulling 63930df on Nurdok:feature/important-values-infra
into 99be0d0 on salto-io:main.

@Nurdok Nurdok marked this pull request as ready for review January 14, 2025 12:24
Copy link
Contributor

@shir-reifenberg shir-reifenberg left a comment

Choose a reason for hiding this comment

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

Looks good, added mainly questions :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please add a test covering a case when there are predefinedTypes with important values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

log.timeDebug(() => {
Object.entries(definedTypes).forEach(([typeName, type]) => {
if (finalTypeNames?.has(typeName)) {
log.trace('type %s is marked as final, not adjusting', type.elemID.getFullName())
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure about this... I think in this case we should add important values anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.


const { element: elementDef } = defQuery.query(typeName) ?? {}

const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand something 🤔 If importantValues can only exist on top level types, how can we set them for fields like Group's source.id ?

Copy link
Contributor

Choose a reason for hiding this comment

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

(I know this definitions were there before) commenting again after I saw the okta config with the (profile.login)
something here looks odd to me... WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only top-level types can define important values, but they can use inner values to do so. If we needed to add important values to the inner type instead, it would force all types that have a field with that inner type to consider it an important value, which is less flexible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks!

const { element: elementDef } = defQuery.query(typeName) ?? {}

const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter(
({ value }: ImportantValue) => type.fields[value] !== undefined,
Copy link
Contributor

Choose a reason for hiding this comment

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

just making sure .fields[value] works with dot separated path?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replaced with getTypeInPath which I've refactored to support primitive types. Thanks for the tip!

// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
if (
_.isEmpty(importantValues) &&
(type.annotations === undefined || type.annotations[CORE_ANNOTATIONS.IMPORTANT_VALUES] === undefined)
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this part of the condition needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Otherwise, we instantiate type.annotations or type.annotations['_important_values'] as empty objects, which creates a diff in type nacls.

Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be _.isEmpty(importantValues) || then? I'm probably missing something here, let's talk IRL 😄

Also the comment
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
what does "don't need an override" means?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These conditions and the comment were relevant before I deleted the important value assignments in generateType - back then, some types arrived to this function with some important values that needed to be overridden based on the type's actual field.

Now that I deleted that, I've also simplified the condition and the comment. Thanks!

defQuery: ElementAndResourceDefFinder<Options>
finalTypeNames?: Set<string>
}): void =>
log.timeDebug(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: probably should be trace

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 380 to 381
// Generated duck-typed types may contain default important values that are not relevant,
// so we want to override them at this point where we know what fields are actually relevant.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we need to add important values attributes in the two places ?
isn't this can fully replace https://github.com/salto-io/salto/blob/main/packages/adapter-components/src/fetch/element/type_element.ts#L233 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@Nurdok Nurdok force-pushed the feature/important-values-infra branch from 1baa8be to e646fe5 Compare January 19, 2025 12:52
@Nurdok Nurdok force-pushed the feature/important-values-infra branch from e646fe5 to a986741 Compare January 19, 2025 13:00
Copy link
Contributor

@shir-reifenberg shir-reifenberg left a comment

Choose a reason for hiding this comment

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

Looks great, thanks for this
let's talk IRL on https://github.com/salto-io/salto/pull/7104/files#r1921496870 cause I feel like i'm missing something
approving to unblock as the rest looks 💯

also FYI @netama incase you'd like to take a look

@@ -341,6 +348,64 @@ export const hideAndOmitFields = <Options extends FetchApiDefinitionsOptions>({
})
}, 'hideAndOmitFields')

export const getTypeInPath = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for adjusting & exporting this ! 🔥
As this is now exported can you please 🙏

  1. add a docstring
  2. cover in UT

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done™ and Done™

Comment on lines 373 to 376
if (isPrimitiveType(fieldType)) {
log.warn('field %s in type %s is a primitive type, cannot recurse further', fieldName, type.elemID.getFullName())
return undefined
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This case is not valid as restPath is not empty right? maybe it will be useful in the log?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refined the log message.


const { element: elementDef } = defQuery.query(typeName) ?? {}

const importantValues = (elementDef?.topLevel?.importantValues ?? []).filter(
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks!

// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
if (
_.isEmpty(importantValues) &&
(type.annotations === undefined || type.annotations[CORE_ANNOTATIONS.IMPORTANT_VALUES] === undefined)
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be _.isEmpty(importantValues) || then? I'm probably missing something here, let's talk IRL 😄

Also the comment
// Avoid creating unnecessary annotations for types that don't have important values and don't need an override.
what does "don't need an override" means?

Copy link
Contributor

@shir-reifenberg shir-reifenberg left a comment

Choose a reason for hiding this comment

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

👑

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants