mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-17 07:03:31 +00:00
Add warnings capability for admission webhooks
This commit is contained in:
@@ -169,6 +169,8 @@ type holder struct {
|
||||
|
||||
t *testing.T
|
||||
|
||||
warningHandler *warningHandler
|
||||
|
||||
recordGVR metav1.GroupVersionResource
|
||||
recordOperation string
|
||||
recordNamespace string
|
||||
@@ -203,6 +205,7 @@ func (h *holder) reset(t *testing.T) {
|
||||
h.expectOldObject = false
|
||||
h.expectOptionsGVK = schema.GroupVersionKind{}
|
||||
h.expectOptions = false
|
||||
h.warningHandler.reset()
|
||||
|
||||
// Set up the recorded map with nil records for all combinations
|
||||
h.recorded = map[webhookOptions]*admissionRequest{}
|
||||
@@ -231,6 +234,7 @@ func (h *holder) expect(gvr schema.GroupVersionResource, gvk, optionsGVK schema.
|
||||
h.expectOldObject = oldObject
|
||||
h.expectOptionsGVK = optionsGVK
|
||||
h.expectOptions = options
|
||||
h.warningHandler.reset()
|
||||
|
||||
// Set up the recorded map with nil records for all combinations
|
||||
h.recorded = map[webhookOptions]*admissionRequest{}
|
||||
@@ -314,13 +318,15 @@ func (h *holder) verify(t *testing.T) {
|
||||
defer h.lock.Unlock()
|
||||
|
||||
for options, value := range h.recorded {
|
||||
if err := h.verifyRequest(options.converted, value); err != nil {
|
||||
if err := h.verifyRequest(options, value); err != nil {
|
||||
t.Errorf("version: %v, phase:%v, converted:%v error: %v", options.version, options.phase, options.converted, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *holder) verifyRequest(converted bool, request *admissionRequest) error {
|
||||
func (h *holder) verifyRequest(webhookOptions webhookOptions, request *admissionRequest) error {
|
||||
converted := webhookOptions.converted
|
||||
|
||||
// Check if current resource should be exempted from Admission processing
|
||||
if admissionExemptResources[gvr(h.recordGVR.Group, h.recordGVR.Version, h.recordGVR.Resource)] {
|
||||
if request == nil {
|
||||
@@ -357,6 +363,10 @@ func (h *holder) verifyRequest(converted bool, request *admissionRequest) error
|
||||
return fmt.Errorf("unexpected options: %#v", request.Options.Object)
|
||||
}
|
||||
|
||||
if !h.warningHandler.hasWarning(makeWarning(webhookOptions.version, webhookOptions.phase, webhookOptions.converted)) {
|
||||
return fmt.Errorf("no warning received from webhook")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -384,6 +394,34 @@ func (h *holder) verifyOptions(options runtime.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type warningHandler struct {
|
||||
lock sync.Mutex
|
||||
warnings map[string]bool
|
||||
}
|
||||
|
||||
func (w *warningHandler) reset() {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
w.warnings = map[string]bool{}
|
||||
}
|
||||
func (w *warningHandler) hasWarning(warning string) bool {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
return w.warnings[warning]
|
||||
}
|
||||
func makeWarning(version string, phase string, converted bool) string {
|
||||
return fmt.Sprintf("%v/%v/%v", version, phase, converted)
|
||||
}
|
||||
|
||||
func (w *warningHandler) HandleWarningHeader(code int, agent string, message string) {
|
||||
if code != 299 || len(message) == 0 {
|
||||
return
|
||||
}
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
w.warnings[message] = true
|
||||
}
|
||||
|
||||
// TestWebhookAdmissionWithWatchCache tests communication between API server and webhook process.
|
||||
func TestWebhookAdmissionWithWatchCache(t *testing.T) {
|
||||
testWebhookAdmission(t, true)
|
||||
@@ -399,6 +437,7 @@ func testWebhookAdmission(t *testing.T, watchCache bool) {
|
||||
// holder communicates expectations to webhooks, and results from webhooks
|
||||
holder := &holder{
|
||||
t: t,
|
||||
warningHandler: &warningHandler{warnings: map[string]bool{}},
|
||||
gvrToConvertedGVR: map[metav1.GroupVersionResource]metav1.GroupVersionResource{},
|
||||
gvrToConvertedGVK: map[metav1.GroupVersionResource]schema.GroupVersionKind{},
|
||||
}
|
||||
@@ -451,6 +490,7 @@ func testWebhookAdmission(t *testing.T, watchCache bool) {
|
||||
clientConfig := rest.CopyConfig(server.ClientConfig)
|
||||
clientConfig.Impersonate.UserName = testClientUsername
|
||||
clientConfig.Impersonate.Groups = []string{"system:masters", "system:authenticated"}
|
||||
clientConfig.WarningHandler = holder.warningHandler
|
||||
client, err := clientset.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
@@ -1265,6 +1305,9 @@ func newV1beta1WebhookHandler(t *testing.T, holder *holder, phase string, conver
|
||||
review.Kind = ""
|
||||
review.Response.UID = ""
|
||||
|
||||
// test plumbing warnings back to the client
|
||||
review.Response.Warnings = []string{makeWarning("v1beta1", phase, converted)}
|
||||
|
||||
// If we're mutating, and have an object, return a patch to exercise conversion
|
||||
if phase == mutation && len(review.Request.Object.Raw) > 0 {
|
||||
review.Response.Patch = []byte(`[{"op":"add","path":"/foo","value":"test"}]`)
|
||||
@@ -1355,6 +1398,9 @@ func newV1WebhookHandler(t *testing.T, holder *holder, phase string, converted b
|
||||
Allowed: true,
|
||||
UID: review.Request.UID,
|
||||
Result: &metav1.Status{Message: "admitted"},
|
||||
|
||||
// test plumbing warnings back
|
||||
Warnings: []string{makeWarning("v1", phase, converted)},
|
||||
}
|
||||
// If we're mutating, and have an object, return a patch to exercise conversion
|
||||
if phase == mutation && len(review.Request.Object.Raw) > 0 {
|
||||
|
Reference in New Issue
Block a user