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

Add reflect lib for auto generation #1205

Merged
merged 14 commits into from
May 31, 2024
Merged

Conversation

wsquan171
Copy link
Contributor

@wsquan171 wsquan171 commented May 7, 2024

This PR is a continuation of previous work by @annakhm on test-reflect branch on the following aspects.

Functional

  • Support conversion of primitive schema types: int, bool, string
  • Support conversion of nested schema types: list, set
  • Nested struct in sdk model should be represented as list with at most 1 element, with metadata SchemaType set to struct
  • List or set of primitive data types (int, bool, string) should use *ExtendedSchema as Schema.Elem
  • List or set of struct data types should use *ExtendedResource as Schema.Elem, and set Metadata.ReflectType to the type of element type in the slice, rather than a slice type.
  • UT under metadata/metaddata_test.go can be referenced as example use cases.

Non-Functional

  • Refactored reflect code into own package for adding isolated UT
  • Moved version check logic to utils package, so both nsxt and metadata package can share the code
  • Added Github action for UT

TBD in a future PR

  • Support of polymorphous struct or list of structs
  • Support of Schema.TypeMap

@vmwclabot vmwclabot added the dco-required DCO Required label May 7, 2024
@wsquan171 wsquan171 force-pushed the test-reflect branch 2 times, most recently from d372589 to 2fa3325 Compare May 7, 2024 22:26
@vmwclabot vmwclabot removed the dco-required DCO Required label May 7, 2024
@vmware vmware deleted a comment from vmwclabot May 7, 2024
@vmware vmware deleted a comment from vmwclabot May 7, 2024
@wsquan171
Copy link
Contributor Author

/test-all

1 similar comment
@wsquan171
Copy link
Contributor Author

/test-all

nsxt/metadata/metadata.go Outdated Show resolved Hide resolved
@@ -98,28 +163,20 @@ func resourceNsxtPolicyMacDiscoveryProfileCreate(d *schema.ResourceData, m inter
return err
}

// TODO - consider including standard object attributes in the schema
tags := getPolicyTagsFromSchema(d)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we want to include tags, display_name and description in the extended schema?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not hard to improve GetExtendedSchema and make it return common extended schema for some well-known policy attrs, but it'll need some refactor on the test side of stuff to make everything e2e working. Can we tackle this after the polymorphic struct is addressed?

@annakhm
Copy link
Collaborator

annakhm commented May 13, 2024

Lets make sure we cover the following use cases, either in unit tests or with a resource:

  • list of native types (int, string, bool)
  • set of native types
  • list of structs
  • set of structs
  • pointer to struct in the model (list of with maxItems = 1)
  • double-nested struct or list of structs
  • list of polymorphic structs (next PR)
  • set of polymorphic structs (next PR)
  • pointer to polymorphic struct (next PR)

@wsquan171 wsquan171 force-pushed the test-reflect branch 2 times, most recently from 0dabad9 to fe820f1 Compare May 21, 2024 19:14
@wsquan171
Copy link
Contributor Author

/test-all

} else {
sliceElem.Index(i).Set(reflect.ValueOf(v))
}
log.Printf("[INFO] appending %v to %s", v, key)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think those printouts should be TRACE level, and we might want to preface them with some keyword so that the context of conversion is clear

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved most to TRACE, except for the ones logged before returning an error.

}

if len(itemList) == 0 {
continue
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if here we might run into a problem of assigning nil value to array instead of assigning empty array?
We need to be able to remove a list of values from a struct, and in some cases nil value would be ignored by the Patch call.
We can leave this as is for now, and consider adding another metadata value that would control this behavior when the need arises.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch. I actually think there is no harm in passing an empty slice if tf schema is empty. For create this is a no op, and for update this is an explict erasure. We can revisit this part if other handling for erasing is needed for some NSX resources.

Copy link
Member

@salv-orlando salv-orlando left a comment

Choose a reason for hiding this comment

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

Test module looks good enough. Only a few questions inline.

nsxt/metadata/metadata.go Outdated Show resolved Hide resolved
if len(parent) > 0 {
log.Printf("[INFO] parent %s key %s", parent, key)
}
if elem.FieldByName(item.Metadata.SdkFieldName).IsNil() {
Copy link
Member

Choose a reason for hiding this comment

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

According to golang doc, FieldByName will return 0 if the field is not found.
If the method is invoked with the right parameters this should never happen, but in theory it should be possible to have a condition where item.Metadata.SdkFieldName is not defined in elem. If that's correct, adding an additional check would not hurt.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agree with Salvatore, we should ease troubleshooting for bad metadata arguments that will inevitably occur

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added check for elem.FieldByName(item.Metadata.SdkFieldName).IsValid() and returns error if the field is not found


log.Printf("[INFO] inspecting key %s with type %s", key, item.Metadata.SchemaType)
if len(parent) > 0 {
log.Printf("[INFO] parent %s key %s", parent, key)
Copy link
Member

Choose a reason for hiding this comment

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

If there is value in this log line, we should consider printing something also if len(parent)<=0 since we are also emitting key in the log statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added the info of parent as part of context prefix as Anna suggested.

wsquan171 added 6 commits May 29, 2024 10:23
Signed-off-by: Shawn Wang <[email protected]>
In terraform, optional fields all comes with default value.
No need to leave them as empty pointer in the reflected struct.

Signed-off-by: Shawn Wang <[email protected]>
This change improves logging with:
- include filename and line for log print in metadata pkg
- switch to TRACE
- add context of the struct being handled

Signed-off-by: Shawn Wang <[email protected]>
If tf schema is updated to empty, the sdk obj should be updated to empty
slice instead of nil slice, so that it will be in the PATCH call to
remove and clear the list on NSX

Signed-off-by: Shawn Wang <[email protected]>
This change improves error checking and reporting in the reflect lib.
Now an error will be returned on both convert directions if either:
- The name of a field is not found in the passed in struct
- reflect called panic for whatever operation failed

Signed-off-by: Shawn Wang <[email protected]>
@wsquan171
Copy link
Contributor Author

/test-all

@wsquan171 wsquan171 merged commit 09cd1f2 into vmware:master May 31, 2024
8 checks passed
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.

4 participants