Skip to content

Conversation

@mikhail-aws
Copy link
Contributor

@mikhail-aws mikhail-aws commented Nov 28, 2023

Note

Add generic policy handler and refactor IAMAuthPolicy, TargetGroupPolicy, VpcAssociationPolicy with use of generic handler.

Testing:

  • e2e-test
  • Manual tests around setting correct statuses for different policies

Generic Policy Handler

The high-level design is to introduce generic helper struct with collection of different methods to work with Policy CRD's. This helper/handler is supposed to be used in controllers that interact with Policy CRDs.

Controller's code should explicitly call different, and relatively small methods of handler, so that it should be easy to tell what controller does looking at controller's code.

Code includes some arcane golang around generics. For example:

func NewPolicyHandler[T, TL any, P policyPtr[T], PL policyListPtr[TL, P]](cfg PolicyHandlerConfig) *PolicyHandler[P] {

These 4 generic types methods are results of having 2 types of policy structs Policy and PolicyList in every CRD. Also I need to make distinction between Policy and ref type *Policy for some functionality related to k8s client calls - Get and List.

All generic complexity stays in Policy file but interface is still simple with single type and I believe understandable methods.
PolicyHandler creation is as simple as it can be.

         type iap = anv1alpha1.IAMAuthPolicy
         type iapl = anv1alpha1.IAMAuthPolicyList

         phcfg PolicyHandlerConfig := PolicyHandlerConfig{}
         _ = NewPolicyHandler[iap, iapl](cfg: phcfg)

It's a not valid config to call all methods, but it's enough for compiler to understand it's IAMAuthPolicy and all related methods will be statically checked.

Partly address: #508

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

@solmonk solmonk changed the title Add generic policy handler and refactor IAM Auth Polciy Add generic policy handler and refactor IAM Auth Policy Nov 28, 2023
@solmonk
Copy link
Contributor

solmonk commented Nov 29, 2023

I was thinking of getting rid of pointer definition and came up with this example, what do you think?
https://github.com/solmonk/aws-application-networking-k8s/blob/refactor-policy-poc/pkg/k8s/policyhelper/policy.go#L229-L237
You might not like using runtime reflect functions but we can back this up by having proper unit test case. (https://github.com/solmonk/aws-application-networking-k8s/blob/refactor-policy-poc/pkg/k8s/policyhelper/policy_test.go#L247-L256)

@mikhail-aws
Copy link
Contributor Author

mikhail-aws commented Nov 29, 2023

I was thinking of getting rid of pointer definition and came up with this example, what do you think? https://github.com/solmonk/aws-application-networking-k8s/blob/refactor-policy-poc/pkg/k8s/policyhelper/policy.go#L229-L237 You might not like using runtime reflect functions but we can back this up by having proper unit test case. (https://github.com/solmonk/aws-application-networking-k8s/blob/refactor-policy-poc/pkg/k8s/policyhelper/policy_test.go#L247-L256)

4 tuple of types isnt that bad as it looks like, especially pointerType can be derived from structType and I dont need explicit type declaration. I dont think it worth replacing it with reflection. I end up with smaller helper constructor functions that simplifies usage outside of policy.go.

As I mentioned before we still need to maintain mapping between single and plural crd structs.

For example:

 func NewVpcAssociationPolicyHandler(log gwlog.Logger, c k8sclient.Client) *PolicyHandler[*VAP] {
         phcfg PolicyHandlerConfig := PolicyHandlerConfig{
                 Log:            log,
                 Client:         c,
                 TargetRefKinds: NewGroupKindSet(objs...: &gwv1beta1.Gateway{}),
         }
         return NewPolicyHandler[VAP, VAPL](cfg: phcfg)
 }

Copy link
Member

@xWink xWink left a comment

Choose a reason for hiding this comment

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

Some small comments. Also would like to see unit tests on the new policy helper functions.

@solmonk
Copy link
Contributor

solmonk commented Nov 29, 2023

I feel like this PR kinda gives a vibe of a sophisticated TypeScript code doing type circuses.

Doing a recap of why I thought this was hard to read:

  • need to understand relationship between T, U, P, and PL. so P is a pointer of T and PL is a pointer of U
  • need to understand relationship between type constraints in different structs. policyListPtr's T is policyClient's TL
  • the name policyPtr sounds like a interface ptr but actually a struct ptr pointing to underlying policy implementation
  • U doesn't relate to any initial of an object, should be TL or something else?
  • T is an any type which doesn't say much by itself, and can't actually constraint anything (I think this is most critical)

If we manage to reduce it to just P and PL I think it is more consistent and readable (I mean, except for a few lines of reflection magic)

And I'm okay with having both single and list types on handler generics. I think it has benefits, as you mentioned.

@mikhail-aws
Copy link
Contributor Author

@solmonk I agree it would be nicer to have only 2 types: policy and list. I dont mind to follow up after this pr, currently this behavior is isolated to local k8sClient struct and not exposed outside, it should be an easy change after.

@mikhail-aws mikhail-aws changed the title Add generic policy handler and refactor IAM Auth Policy Add generic policy handler; refactor IAMAuthPolicy, TargetGroupPolicy, VpcAssociationPolicy Nov 30, 2023
@mikhail-aws
Copy link
Contributor Author

@xWink addressed minor comments, but not unit tests. I will do follow-up on this PR with unit tests, currently it's being manually tested and ran full e2e test suite.

@xWink
Copy link
Member

xWink commented Nov 30, 2023

LGTM. Thanks for putting this together!

@mikhail-aws mikhail-aws merged commit 9eafcb7 into aws:main Nov 30, 2023
@mikhail-aws mikhail-aws deleted the refactor-policy branch November 30, 2023 20:08
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