mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-23 22:46:53 +00:00
[Backport release-1.5] Fix: reject applications with empty policy properties (#4566)
* Fix: reject applications with empty policies Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com> (cherry picked from commit337032511e) * Style: change err msg Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com> (cherry picked from commit2bb5c0245a) * Fix: use 400 instead of 422 to show err msg Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com> (cherry picked from commit553ac92c62) * Test: fix tests Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com> (cherry picked from commit0ce352d13b) Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
This commit is contained in:
co-authored by
Charlie Chiang
parent
491127daec
commit
6d979cfcab
@@ -381,6 +381,9 @@ func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (er
|
||||
return err
|
||||
}
|
||||
for _, policy := range af.Policies {
|
||||
if policy.Properties == nil && policy.Type != v1alpha1.DebugPolicyType {
|
||||
return fmt.Errorf("policy %s named %s must not have empty properties", policy.Type, policy.Name)
|
||||
}
|
||||
switch policy.Type {
|
||||
case v1alpha1.GarbageCollectPolicyType:
|
||||
case v1alpha1.ApplyOncePolicyType:
|
||||
@@ -407,6 +410,9 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
|
||||
return err
|
||||
}
|
||||
for _, policy := range af.Policies {
|
||||
if policy.Properties == nil && policy.Type != v1alpha1.DebugPolicyType {
|
||||
return fmt.Errorf("policy %s named %s must not have empty properties", policy.Type, policy.Name)
|
||||
}
|
||||
switch policy.Type {
|
||||
case v1alpha1.GarbageCollectPolicyType:
|
||||
case v1alpha1.ApplyOncePolicyType:
|
||||
|
||||
@@ -269,6 +269,20 @@ spec:
|
||||
image: "busybox"
|
||||
`
|
||||
|
||||
const appfileYamlEmptyPolicy = `
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: application-sample
|
||||
namespace: default
|
||||
spec:
|
||||
components: []
|
||||
policies:
|
||||
- type: garbage-collect
|
||||
name: somename
|
||||
properties:
|
||||
`
|
||||
|
||||
var _ = Describe("Test application parser", func() {
|
||||
It("Test we can parse an application to an appFile", func() {
|
||||
o := v1beta1.Application{}
|
||||
@@ -314,6 +328,14 @@ var _ = Describe("Test application parser", func() {
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = NewApplicationParser(&tclient, dm, pd).GenerateAppFile(context.TODO(), ¬found)
|
||||
Expect(err).Should(HaveOccurred())
|
||||
|
||||
By("app with empty policy")
|
||||
emptyPolicy := v1beta1.Application{}
|
||||
err = yaml.Unmarshal([]byte(appfileYamlEmptyPolicy), &emptyPolicy)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = NewApplicationParser(&tclient, dm, pd).GenerateAppFile(context.TODO(), &emptyPolicy)
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).Should(ContainSubstring("have empty properties"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -96,7 +96,9 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
|
||||
switch req.Operation {
|
||||
case admissionv1.Create:
|
||||
if allErrs := h.ValidateCreate(ctx, app); len(allErrs) > 0 {
|
||||
return admission.Errored(http.StatusUnprocessableEntity, mergeErrors(allErrs))
|
||||
// http.StatusUnprocessableEntity will NOT report any error descriptions
|
||||
// to the client, use generic http.StatusBadRequest instead.
|
||||
return admission.Errored(http.StatusBadRequest, mergeErrors(allErrs))
|
||||
}
|
||||
case admissionv1.Update:
|
||||
oldApp := &v1beta1.Application{}
|
||||
@@ -105,7 +107,7 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
|
||||
}
|
||||
if app.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
if allErrs := h.ValidateUpdate(ctx, app, oldApp); len(allErrs) > 0 {
|
||||
return admission.Errored(http.StatusUnprocessableEntity, mergeErrors(allErrs))
|
||||
return admission.Errored(http.StatusBadRequest, mergeErrors(allErrs))
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -452,4 +452,21 @@ var _ = Describe("Test Application Validator", func() {
|
||||
resp = handler.Handle(ctx, req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("Test Application with empty policy", func() {
|
||||
req := admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1beta1", Resource: "applications"},
|
||||
Object: runtime.RawExtension{
|
||||
Raw: []byte(`
|
||||
{"kind":"Application","metadata":{"name":"app-with-empty-policy-webhook-test", "namespace":"default"},
|
||||
"spec":{"components":[],"policies":[{"name":"2345","type":"garbage-collect","properties":null}]}}
|
||||
`),
|
||||
},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(ctx, req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -118,13 +118,14 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
|
||||
if err := h.Decoder.DecodeRaw(req.AdmissionRequest.OldObject, oldApp); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
if allErrs := h.ValidateUpdate(ctx, app, oldApp); len(allErrs) > 0 {
|
||||
return admission.Errored(http.StatusUnprocessableEntity, allErrs.ToAggregate())
|
||||
// http.StatusUnprocessableEntity will NOT report any error descriptions
|
||||
// to the client, use generic http.StatusBadRequest instead.
|
||||
return admission.Errored(http.StatusBadRequest, allErrs.ToAggregate())
|
||||
}
|
||||
case admissionv1.Create:
|
||||
if allErrs := h.ValidateCreate(ctx, app); len(allErrs) > 0 {
|
||||
return admission.Errored(http.StatusUnprocessableEntity, allErrs.ToAggregate())
|
||||
return admission.Errored(http.StatusBadRequest, allErrs.ToAggregate())
|
||||
}
|
||||
default:
|
||||
// Do nothing for CONNECT
|
||||
|
||||
Reference in New Issue
Block a user