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
Collaborator

@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

@wsquan171 wsquan171 force-pushed the test-reflect branch 2 times, most recently from d372589 to 2fa3325 Compare May 7, 2024 22:26
@vmware vmware deleted a comment from vmwclabot May 7, 2024
@vmware vmware deleted a comment from vmwclabot May 7, 2024
@wsquan171
Copy link
Collaborator Author

/test-all

1 similar comment
@wsquan171
Copy link
Collaborator 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
Collaborator 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
Collaborator 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
Collaborator 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
Collaborator 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
Collaborator 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
Collaborator 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.

annakhm and others added 7 commits May 29, 2024 10:13
Signed-off-by: Anna Khmelnitsky <akhmelnitsky@vmware.com>
Signed-off-by: Anna Khmelnitsky <akhmelnitsky@vmware.com>
Signed-off-by: Anna Khmelnitsky <akhmelnitsky@vmware.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
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 <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
Signed-off-by: Shawn Wang <shawn.wang@broadcom.com>
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 <shawn.wang@broadcom.com>
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 <shawn.wang@broadcom.com>
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 <shawn.wang@broadcom.com>
@wsquan171
Copy link
Collaborator 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.

None yet

4 participants