-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[feat gw api] Add Gateway Class Reconciler + Config merging logic. #4163
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
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: zac-nixon 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 |
merged.EnableICMP = lowPriority.Spec.EnableICMP | ||
} | ||
|
||
if highPriority.Spec.ManageBackendSecurityGroupRules != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish Go had ternary testing operation :(
mergingMode defines the merge behavior when both the Gateway and GatewayClass have a defined LoadBalancerConfiguration. | ||
This field is only honored for the configuration attached to the GatewayClass. | ||
enum: | ||
- prefer-gateway |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am think should we be more specific in naming, cuz the name mergingMode
does not imply it is for lbConfig and enum does not imply it too. Users can read doc for sure but maybe we can try to make name more explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merging mode only exists within the LoadBalancer configuration, I felt it would be redundant to re-state that the merging mode is specific to the LB.
|
||
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) { | ||
lbconfig := e.Object | ||
h.logger.V(1).Info("enqueue loadbalancerconfiguration delete event", "loadbalancerconfiguration", lbconfig.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we also wanna logging namespace? (if name can be same for different namespace)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah good idea
} | ||
} | ||
|
||
func (merger *configMergerImpl) performTakeOneMerges(merged *elbv2gw.LoadBalancerConfigurationSpec, highPriority elbv2gw.LoadBalancerConfiguration, lowPriority elbv2gw.LoadBalancerConfiguration) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like in this function, it is assume if a property is not specified in highPriority spec, it will be specified in low priority spec, but what if lowPriority.Spec.LoadBalancerName
is also nil (unless it is never gonna be the case), and if we originally have a default value for LoadBalancerName, then after this function, the default value will be overriden and it is gonna be nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow -- The merged spec starts off w/ a blank spec, so it's all zero values. We will always use the high priority value (if it exists) otherwise we use the low priority value, which could be a real value or a zero value. If it's a zero value, the merged spec still has a zero value which is correct.
I don't think it's possible we ever start with a default value for the load balancer name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see, thanks for the explanation
|
||
func (r *gatewayReconciler) getLoadBalancerConfigForGateway(ctx context.Context, k8sClient client.Client, gw *gwv1.Gateway, gwClass *gwv1.GatewayClass) (elbv2gw.LoadBalancerConfiguration, error) { | ||
|
||
// If the Gateway Class isn't accepted, we shouldn't try to reconcile this Gateway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this check outside of this function in the main reconciler so that this function sticks to just getting the lb config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
if storedVersion != nil { | ||
safeVersion = *storedVersion | ||
} | ||
return elbv2gw.LoadBalancerConfiguration{}, errors.Errorf("GatewayClass [%s] hasn't processed latest loadbalancer config. Processed version %s, Latest version %s", gwClass.Name, safeVersion, gatewayClassLBConfig.ResourceVersion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of throwing error, do we want to retry/wait for gwclass to complete its processing its cfg?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing an error is the same thing as wait + retry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok got it.
@@ -62,7 +65,7 @@ func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Generic(ctx context.C | |||
} | |||
|
|||
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) enqueueImpactedService(ctx context.Context, lbconfig *elbv2gw.LoadBalancerConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) { | |||
gwClasses := GetImpactedGatewayClassesFromLbConfig(ctx, h.k8sClient, lbconfig, h.gwController) | |||
gwClasses := GetImpactedGatewayClassesFromLbConfig(ctx, h.k8sClient, lbconfig, h.gwControllerSet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we have separate controller for gateway class? Do we even need to enqueue gwclass for LB config changes in gateway controller?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.
They serve two different purposes.
In the GatewayClass reconciler, it's meant to validate the configuration is valid and move the Gateway Class status to Accepted.
In the Gateway reconciler, it's meant to materialize the ELB resources according to the Gateway config.
} | ||
|
||
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Create(ctx context.Context, e event.TypedCreateEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) { | ||
// We don't need to respond to create events. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the gwclass is created first referencing a non-existing cfg, user realises his mistake as they see not found status on the gwclass and decides to create the lbcfg now? We need to listen to this event and enqueue the gwclass referencing it to update its status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should already been handled, because we have the event queued for the gwclass creation. Since it failed to find the config, it will keep reconciling. Eventually when the config is created, everything should just work.
/lgtm |
Description
Adds a reconciler to process Gateway Class changes, including changes to LoadBalancer configurations attached to a Gateway Class.
Adds basic logic to ensure that Gateway reconciler will only progress Gateways that have an accepted Gateway Class.
Adds a configuration merger that implements merging logic to handle GatewayClass and Gateway LoadBalancer configs. [TODO: Add documentation]
Refactored to drop pointer references to the the lb config in the gateway model builders, this removes the need for nil checks in all of the model builders.
Checklist
README.md
, or thedocs
directory)BONUS POINTS checklist: complete for good vibes and maybe prizes?! 🤯