-
Notifications
You must be signed in to change notification settings - Fork 130
feat: Add ability to patch dataplane Service, Deployment, and DaemonSet in NginxProxy #3630
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
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3630 +/- ##
==========================================
- Coverage 86.87% 86.85% -0.03%
==========================================
Files 127 127
Lines 15287 15354 +67
Branches 62 62
==========================================
+ Hits 13281 13335 +54
- Misses 1851 1860 +9
- Partials 155 159 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
// For JSONPatch patches, this should be a JSON array of patch operations. | ||
// | ||
// +kubebuilder:validation:XPreserveUnknownFields | ||
Value *apiextv1.JSON `json:"value"` |
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.
Should this field be marked as optional?
if len(errs) > 0 { | ||
return objects, errors.Join(errs...) | ||
} | ||
|
||
return objects, 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 think you could just do return objects, errors.Join(errs...)
. If errs is empty, it should return nil.
|
||
const ( | ||
// PatchTypeStrategicMerge uses strategic merge patch. | ||
PatchTypeStrategicMerge PatchType = "StrategicMerge" |
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.
Does k8s define these types at all? If so, it'd be nice to alias our types to theirs, instead of using the string literal.
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 there are some definitions here: https://github.com/kubernetes/apimachinery/blob/1ebcba2516a6683ca3be753b0b7e2cb203daf5dd/pkg/types/patch.go#L22
Which are used in the apiextentions-apiserver test code here: https://github.com/kubernetes/apiextensions-apiserver/blob/9fbc252b2071ab031a4011dd3d07fde4e281fe3c/test/integration/scope_test.go#L132-L138
@@ -537,6 +567,15 @@ func (p *NginxProvisioner) buildNginxDeployment( | |||
Template: podTemplateSpec, | |||
}, | |||
} | |||
|
|||
// Apply DaemonSet patches | |||
if nProxyCfg.Kubernetes.DaemonSet != 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.
Isn't this if statement
not needed since the check is already above?
if nProxyCfg != nil && nProxyCfg.Kubernetes != nil && nProxyCfg.Kubernetes.Deployment != nil { | ||
if err := applyPatches(deployment, nProxyCfg.Kubernetes.Deployment.Patches); err != nil { | ||
return deployment, fmt.Errorf("failed to apply deployment patches: %w", err) | ||
} | ||
} |
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.
nit: can we combine the above line
if nProxyCfg != nil && nProxyCfg.Kubernetes != nil && nProxyCfg.Kubernetes.Deployment != nil {
deploymentCfg = *nProxyCfg.Kubernetes.Deployment
}
into this statement?
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.
if its possible, can you add another test case where a patch later on in the array overrides a field set in a previous patch?
Proposed changes
Problem: There are many Deployment and Service fields that can be customized, and having to expose all of them in the NginxProxy resource is tedious and unnecessary for uncommonly used fields.
Solution: Add a way to submit custom patches to unblock users who need to set fields that are not yet exposed in the NginxProxy CRD. This commit adds support for patching the Service, Deployment, and DaemonSet resources using StrategicMerge (default kubernetes patch strategy), Merge (used when the intelligent strategic merge behaviour is not desired, e.g. to replace an array instead of merging them), and JSONPatch (used when precise modifications are needed, such as adding elements to specific array indices or performing conditional operations based on existing values).
Testing: Unit testing, and manual testing all the variations. Example NginxProxy:
Note 1: We don't have the ability to perform validation on patches. Errors in Patches will be logged in the control plane, but will not be reported in the status of the NginxProxy. Additionally, the resources will be created regardless - I don't believe we should fail the resource creation because of patch errors. It will be on the user to ensure patches have been applied correctly (this will be documented in the data plane configuration doc)
Note 2: Uses
gopkg.in/evanphx/json-patch.v4
instead of the latest v5 to match Kubernetes ecosystem libraries and ensure consistent RFC 6902 compliance with kubectl. See this issue for a similar exampleCloses #3568
Checklist
Before creating a PR, run through this checklist and mark each as complete.
Release notes
If this PR introduces a change that affects users and needs to be mentioned in the release notes,
please add a brief note that summarizes the change.