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

Support of injecting fields in existing structures: CustomNestedFields #462

Merged
merged 5 commits into from
Sep 27, 2023

Conversation

Vandita2020
Copy link
Member

@Vandita2020 Vandita2020 commented Aug 23, 2023

Issue #
This issue arises from the code changes in lambda-controller for PR #88

Summary
Support of injecting fields in existing structures: CustomNestedFields

Description
The code in this PR helps in accepting a custom nestedField defined using type as a part of its parentField. In the issue mentioned above when we inject a new field S3SHA256 into Code struct, instead of nesting it under Code the generator created a separate field named CodeS3SHA256.

The new field S3SHA256 is defined like this in generator.yaml file:

Function:
    fields:
      Code.S3SHA256:
        type: string

After applying the changes in this PR, the field S3SHA256 is properly injected as a part of Code struct.

type FunctionCode struct {
	ImageURI *string `json:"imageURI,omitempty"`
	S3Bucket *string `json:"s3Bucket,omitempty"`
	S3BucketRef     *ackv1alpha1.AWSResourceReferenceWrapper `json:"s3BucketRef,omitempty"`
	S3Key           *string                                  `json:"s3Key,omitempty"`
	S3ObjectVersion *string                                  `json:"s3ObjectVersion,omitempty"`
	S3SHA256        *string                                  `json:"s3SHA256,omitempty"`
	ZipFile         []byte                                   `json:"zipFile,omitempty"`
} 

This PR contains code implementation to inject Nested fields into the Spec or Status struct and has respective model-test to validate the changes.

Acknowledgment
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

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

@Vandita2020 This is great work, well done!
I left a few comments to improve the code and make it more similar to what we have in the other packages.

Comment on lines 1 to 3
{
"go.buildTags": "codegen",
}
Copy link
Member

Choose a reason for hiding this comment

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

Do not commit this please. Maybe let's add .vscode/settings.json to .gitignore file ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd even recommend adding .vscode to a global gitignore on your system. Otherwise every repo needs to add every IDE's config paths (.vscode, .idea, etc.) individually.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, thanks!

Comment on lines 84 to 93
func CheckIfFieldExists(
field map[string]*Field,
currValue string,
) bool {
_, ok := field[currValue]
if ok {
return true
}
return false
}
Copy link
Member

Choose a reason for hiding this comment

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

Mmmmm i think this is unecessary.. it will always fall down to:

                  if _, ok := fieldsInParent[parent]; ok {
						// Check if the field is of type structure
						previous, res = CheckType(value, fieldsInParent)
						if res != true {
							fmt.Printf("Cannot add new field here, %s is not of type Structure", parentName)
							break
						}
					}

return false
}

func CheckType(
Copy link
Member

Choose a reason for hiding this comment

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

Same comment here, i don't think we need this function.. or the least it should be named isShapeStructure .. and still not very convinced of moving this logic to a function

Copy link
Member Author

Choose a reason for hiding this comment

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

Have removed the function and added the logic to the calling function

Comment on lines 52 to 55
type Nested struct {
arr []string
Config *ackgenconfig.FieldConfig
}
Copy link
Member

Choose a reason for hiding this comment

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

i know this is working. Pretty sure we can find a better way to represent this data.. (i think we are copying a lot arr)

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't actually get what you mean by copying arr data a lot. It is just defined once to store the names of nested fields and is then iterated over to check the nested fields type and whether they are a part of their parent field. But yeah I'm open to looking for a better way to represent the data.


for _, toInjectNestedFields := range alltoInjectNestedFields {

addThis := ""
Copy link
Member

Choose a reason for hiding this comment

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

need a better name than addThis

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed the name to newCustomField. Let me know if that sounds okay.

var previous *Field
var res bool

len := len(toInjectNestedFields.arr)
Copy link
Member

Choose a reason for hiding this comment

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

len is a Go keyword, i suggest just to use len(toInjectNestedFields.arr) whenever you need to.

Comment on lines +129 to +130
assert.Contains(codeField.MemberFields, "S3SHA256")
assert.Contains(codeField.ShapeRef.Shape.MemberRefs, "S3SHA256")
Copy link
Member

Choose a reason for hiding this comment

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

Good testing!

f := NewField(crd, fPath, memberNames, shapeRef, fConfig)
crd.Fields[fPath] = f

previous.MemberFields[addThis] = f
Copy link
Member

Choose a reason for hiding this comment

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

👍

Comment on lines 359 to 329
// first element is a field of CRD
fieldsInCRD := crd.SpecFields
Copy link
Member

Choose a reason for hiding this comment

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

This could have been declared outside, it's a non necessary operation to do at every loop (same for few variables below)

Copy link
Member Author

Choose a reason for hiding this comment

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

There is a relation between fieldsInParent and previous variable, which changes with every loop. I can declare the fieldsInCRD outside the loop, but that is the only variable that can be defined outside the loop. To maintain the code readability I declared it the same way as fieldsInParent.

if CheckIfFieldExists(fieldsInCRD, value) {
// Check if the field is of type structure
previous, res = CheckType(value, fieldsInCRD)
if res != true {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if res != true {
if !res {

Copy link
Member Author

Choose a reason for hiding this comment

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

This whole part is removed now

@a-hilaly
Copy link
Member

a-hilaly commented Sep 5, 2023

/test apigatewayv2-controller-test

@ack-prow
Copy link

ack-prow bot commented Sep 6, 2023

@Vandita2020: The /test command needs one or more targets.
The following commands are available to trigger required jobs:

  • /test apigatewayv2-controller-test
  • /test dynamodb-controller-test
  • /test ec2-controller-test
  • /test ecr-controller-test
  • /test iam-controller-test
  • /test lambda-controller-test
  • /test s3-controller-test
  • /test unit-test

The following commands are available to trigger optional jobs:

  • /test s3-olm-test

Use /test all to run all jobs.

In response to this:

/test

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@Vandita2020
Copy link
Member Author

/test all

@Vandita2020
Copy link
Member Author

/test dynamodb-controller-test

1 similar comment
@Vandita2020
Copy link
Member Author

/test dynamodb-controller-test

@a-hilaly
Copy link
Member

/test all

@Vandita2020
Copy link
Member Author

/test iam-controller-test

@a-hilaly a-hilaly changed the title Accept custom nestedField defined using 'type' in its parentField Support of injecting fields in existing structures: CustomNestedFields Sep 27, 2023
pkg/model/crd.go Outdated
// inject a field called "Password" into the "User" struct, the field path
// would be "User.Password". The field path can be as deep as needed.
func (crd *CRD) addCustomNestedFields(customNestedFields map[string]*ackgenconfig.FieldConfig) {
// Now that we collected all the nested fields, we can process, validate
Copy link
Member

Choose a reason for hiding this comment

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

What does "now" mean here? The message doesn't seem relevant in the beginning of a function.

pkg/model/crd.go Outdated
topLevelField := fieldParts[0]

f, ok := crd.checkSpecOrStatus(topLevelField)
// f, ok := crd.SpecFields[topLevelField]
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented out code

pkg/model/crd.go Outdated
// and inject them into the Spec or Status struct.
for customNestedField, customNestedFieldConfig := range customNestedFields {
fieldParts := strings.Split(customNestedField, ".")
// we now than the length of fieldParts is at least 2
Copy link
Member

Choose a reason for hiding this comment

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

we know that the length

pkg/model/crd.go Outdated
Comment on lines 667 to 675
// else {
// f, ok = crd.SpecFields[topLevelField]
// if ok && f.ShapeRef.Shape.Type != "structure" {
// // We need to panic here because the user is providing wrong configuration.
// msg := fmt.Sprintf("Expected parent field to be of type structure, but found %s", f.ShapeRef.Shape.Type)
// panic(msg)
// }
// }
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented code

Comment on lines 139 to 140
// A list of fields that should be processed after building the gathering
// the Spec and Status top level fields. The customNestedFields will be
Copy link
Member

Choose a reason for hiding this comment

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

the phrase "after building the gathering the Spec and Status" feels wrong. I think there's an extra word that shouldn't be there.

@a-hilaly
Copy link
Member

/retest

Copy link
Member

@a-hilaly a-hilaly left a comment

Choose a reason for hiding this comment

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

Very nice! Thanks a lot for your contribution @Vandita2020 . This will be beneficial to all the ACK controllers and it's community.
/approve
/lgtm

@ack-prow ack-prow bot added the lgtm Indicates that a PR is ready to be merged. label Sep 27, 2023
@ack-prow
Copy link

ack-prow bot commented Sep 27, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: a-hilaly, Vandita2020

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ack-prow ack-prow bot added the approved label Sep 27, 2023
@a-hilaly
Copy link
Member

/hold

@ack-prow ack-prow bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 27, 2023
@a-hilaly
Copy link
Member

/unhold

@ack-prow ack-prow bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 27, 2023
@ack-prow ack-prow bot merged commit 7445de3 into aws-controllers-k8s:main Sep 27, 2023
ack-prow bot pushed a commit that referenced this pull request Apr 8, 2024
**Issue** 
This PR is related to fix the issue generating after executing PR #462 

**Summary**
To disregard fields marked with `set: ignore` for nested fields. This PR also enhances the functionality of `set:ignore` to support the exclusion of fields from `set_sdk`.

**Description**

The PR  fixes the issue coming after a new custom field is created and has `set.ignore` set to `true` for it. Even after setting the field to ignore, the field is getting used to set the SDK fields. In this case particularly, the new field was defined as shown below:

```
Code.S3SHA256:
        type: string
        set:  
          - method: Create
            ignore: true
```
And the issue it is causing is under `sdk.go/newCreateRequestPayload` function, where it is being set, as shown below:
```
if r.ko.Spec.Code.S3SHA256 != nil {
	f1.SetS3SHA256(*r.ko.Spec.Code.S3SHA256)
}
```
The goal is to ignore this particular line of code. And also to improve the basic functionality of `set.ignore`. 

The `set.ignore` functionality was till now supporting exclusion of fields only when the field was used to set for the resource. 

This PR checks the `set.ignore` for field and ignores the following code that creates request payload if it is set to `true`. 

**Limitations**
Currently this PR checks the `set.ignore` field only for members of the field whose type is `structure`. 

**Acknowledgment**
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants