-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add conditions reset mutating webhook (#324)
* Add conditions reset mutating webhook To ensure that policy conditions are reset at updated policies, this wait a user can safely call kubectl apply and then kubectl wait, since previous conditions are cleaned up. Signed-off-by: Quique Llorente <[email protected]> * Use AddToManager at webhook Refactor webhook so they use similar mechanism like controllers to inject them to the manager. Signed-off-by: Quique Llorente <[email protected]> * Update CA bundle at webhook start Signed-off-by: Quique Llorente <[email protected]> * Use cert manager Signed-off-by: Quique Llorente <[email protected]> * Generalize webhooksever Signed-off-by: Quique Llorente <[email protected]> * Show client-go cert manager logs Signed-off-by: Quique Llorente <[email protected]> * Support validating webhooks Signed-off-by: Quique Llorente <[email protected]> * Review fixes Signed-off-by: Quique Llorente <[email protected]> * Call mod tidy to add gomega gstruct Signed-off-by: Quique Llorente <[email protected]> * Add unit test for reset condition Signed-off-by: Quique Llorente <[email protected]> * Split in two webhooks, one for nncp and other for nncp/status Signed-off-by: Quique Llorente <[email protected]>
- Loading branch information
Showing
497 changed files
with
2,953 additions
and
57,688 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package webhook | ||
|
||
import ( | ||
"github.com/nmstate/kubernetes-nmstate/pkg/webhook/nodenetworkconfigurationpolicy" | ||
) | ||
|
||
func init() { | ||
// AddToManagerFuncs is a list of functions to create controllers and add them to a manager. | ||
AddToManagerFuncs = append(AddToManagerFuncs, nodenetworkconfigurationpolicy.Add) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package nodenetworkconfigurationpolicy | ||
|
||
import ( | ||
corev1 "k8s.io/api/core/v1" | ||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission" | ||
|
||
nmstatev1alpha1 "github.com/nmstate/kubernetes-nmstate/pkg/apis/nmstate/v1alpha1" | ||
) | ||
|
||
var log = logf.Log.WithName("webhook/nodenetworkconfigurationpolicy/conditions") | ||
|
||
func deleteConditions(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) nmstatev1alpha1.NodeNetworkConfigurationPolicy { | ||
policy.Status.Conditions = nmstatev1alpha1.ConditionList{} | ||
return policy | ||
} | ||
|
||
func setConditionsUnknown(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) nmstatev1alpha1.NodeNetworkConfigurationPolicy { | ||
unknownConditions := nmstatev1alpha1.ConditionList{} | ||
for _, conditionType := range nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionTypes { | ||
unknownConditions.Set( | ||
conditionType, | ||
corev1.ConditionUnknown, | ||
"", "") | ||
} | ||
policy.Status.Conditions = unknownConditions | ||
return policy | ||
} | ||
|
||
func atEmptyConditions(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) bool { | ||
return policy.Status.Conditions == nil || len(policy.Status.Conditions) == 0 | ||
} | ||
|
||
func deleteConditionsHook() *webhook.Admission { | ||
return &webhook.Admission{ | ||
Handler: admission.HandlerFunc( | ||
mutatePolicyHandler( | ||
always, | ||
deleteConditions, | ||
)), | ||
} | ||
} | ||
|
||
func setConditionsUnknownHook() *webhook.Admission { | ||
return &webhook.Admission{ | ||
Handler: admission.HandlerFunc( | ||
mutatePolicyHandler( | ||
atEmptyConditions, | ||
setConditionsUnknown, | ||
)), | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
pkg/webhook/nodenetworkconfigurationpolicy/conditions_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package nodenetworkconfigurationpolicy | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook" | ||
|
||
nmstatev1alpha1 "github.com/nmstate/kubernetes-nmstate/pkg/apis/nmstate/v1alpha1" | ||
) | ||
|
||
func expectConditionsUnknown(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) { | ||
numberOfConditionTypes := len(nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionTypes) | ||
ExpectWithOffset(1, policy.Status.Conditions).To(HaveLen(numberOfConditionTypes)) | ||
for _, conditionType := range nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionTypes { | ||
condition := policy.Status.Conditions.Find(conditionType) | ||
ExpectWithOffset(1, condition).ToNot(BeNil()) | ||
ExpectWithOffset(1, condition.Status).To(Equal(corev1.ConditionUnknown)) | ||
ExpectWithOffset(1, condition.Reason).To(Equal(nmstatev1alpha1.ConditionReason(""))) | ||
ExpectWithOffset(1, condition.Message).To(Equal("")) | ||
ExpectWithOffset(1, condition.LastTransitionTime.Time).To(BeTemporally(">", time.Unix(0, 0))) | ||
ExpectWithOffset(1, condition.LastHeartbeatTime.Time).To(BeTemporally(">", time.Unix(0, 0))) | ||
} | ||
} | ||
|
||
func callHook(hook *webhook.Admission, request webhook.AdmissionRequest) webhook.AdmissionResponse { | ||
|
||
response := hook.Handle(context.TODO(), request) | ||
for _, patch := range response.Patches { | ||
_, err := patch.MarshalJSON() | ||
ExpectWithOffset(2, err).ToNot(HaveOccurred(), "The patches should contain valid JSON") | ||
} | ||
ExpectWithOffset(2, response.Allowed).To(BeTrue(), "Mutation of the request should be allowed") | ||
return response | ||
} | ||
|
||
func callDeleteConditions(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) webhook.AdmissionResponse { | ||
request := requestForPolicy(policy) | ||
return callHook(deleteConditionsHook(), request) | ||
} | ||
|
||
func callSetConditionsUnknown(policy nmstatev1alpha1.NodeNetworkConfigurationPolicy) webhook.AdmissionResponse { | ||
request := requestForPolicy(policy) | ||
return callHook(setConditionsUnknownHook(), request) | ||
} | ||
|
||
var _ = Describe("NNCP Conditions Mutating Admission Webhook", func() { | ||
var ( | ||
obtainedResponse webhook.AdmissionResponse | ||
policy = nmstatev1alpha1.NodeNetworkConfigurationPolicy{} | ||
) | ||
Context("when setConditionsUnknown is called with nil conditions", func() { | ||
BeforeEach(func() { | ||
policy.Status.Conditions = nil | ||
obtainedResponse = callSetConditionsUnknown(policy) | ||
}) | ||
It("should have all policy conditions with Unknown state", func() { | ||
patchedPolicy := patchPolicy(policy, obtainedResponse) | ||
expectConditionsUnknown(patchedPolicy) | ||
}) | ||
|
||
}) | ||
Context("when setConditionsUnknown is called with empty conditions", func() { | ||
BeforeEach(func() { | ||
policy.Status.Conditions = nmstatev1alpha1.ConditionList{} | ||
obtainedResponse = callSetConditionsUnknown(policy) | ||
}) | ||
It("should have all policy conditions with Unknown state", func() { | ||
patchedPolicy := patchPolicy(policy, obtainedResponse) | ||
expectConditionsUnknown(patchedPolicy) | ||
}) | ||
}) | ||
Context("when setConditionsUnknown is called with empty conditions", func() { | ||
BeforeEach(func() { | ||
policy.Status.Conditions = nmstatev1alpha1.ConditionList{} | ||
obtainedResponse = callSetConditionsUnknown(policy) | ||
}) | ||
It("should have all policy conditions with Unknown state", func() { | ||
patchedPolicy := patchPolicy(policy, obtainedResponse) | ||
expectConditionsUnknown(patchedPolicy) | ||
}) | ||
}) | ||
Context("when setConditionsUnknown is called with Some conditions", func() { | ||
BeforeEach(func() { | ||
conditions := nmstatev1alpha1.ConditionList{} | ||
conditions.Set( | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionDegraded, | ||
corev1.ConditionFalse, | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionSuccessfullyConfigured, | ||
"", | ||
) | ||
conditions.Set( | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionAvailable, | ||
corev1.ConditionTrue, | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionSuccessfullyConfigured, | ||
"Foo message", | ||
) | ||
policy.Status.Conditions = conditions | ||
obtainedResponse = callSetConditionsUnknown(policy) | ||
}) | ||
It("should not change the conditions", func() { | ||
Expect(obtainedResponse.Patches).To(BeEmpty()) | ||
}) | ||
|
||
}) | ||
Context("when deleteConditions is called with empty conditions", func() { | ||
BeforeEach(func() { | ||
policy.Status.Conditions = nmstatev1alpha1.ConditionList{} | ||
obtainedResponse = callDeleteConditions(policy) | ||
}) | ||
It("should do nothing", func() { | ||
Expect(obtainedResponse.Patches).To(BeEmpty()) | ||
}) | ||
}) | ||
Context("when deleteConditions is called with some conditions", func() { | ||
BeforeEach(func() { | ||
conditions := nmstatev1alpha1.ConditionList{} | ||
conditions.Set( | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionDegraded, | ||
corev1.ConditionFalse, | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionSuccessfullyConfigured, | ||
"", | ||
) | ||
conditions.Set( | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionAvailable, | ||
corev1.ConditionTrue, | ||
nmstatev1alpha1.NodeNetworkConfigurationPolicyConditionSuccessfullyConfigured, | ||
"Foo message", | ||
) | ||
policy.Status.Conditions = conditions | ||
obtainedResponse = callDeleteConditions(policy) | ||
}) | ||
It("should remove all the conditions", func() { | ||
By(fmt.Sprintf("obtainedResponse: %+v", obtainedResponse)) | ||
patchedPolicy := patchPolicy(policy, obtainedResponse) | ||
Expect(patchedPolicy.Status.Conditions).To(BeEmpty()) | ||
}) | ||
}) | ||
|
||
}) |
Oops, something went wrong.