github.com/oam-dev/kubevela@v1.9.11/pkg/webhook/core.oam.dev/v1beta1/application/validating_handler_test.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package application
    18  
    19  import (
    20  	. "github.com/onsi/ginkgo/v2"
    21  	. "github.com/onsi/gomega"
    22  	admissionv1 "k8s.io/api/admission/v1"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"k8s.io/apimachinery/pkg/runtime"
    25  	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
    26  )
    27  
    28  var _ = Describe("Test Application Validator", func() {
    29  	BeforeEach(func() {
    30  		Expect(handler.InjectClient(k8sClient)).Should(BeNil())
    31  		Expect(handler.InjectDecoder(decoder)).Should(BeNil())
    32  	})
    33  
    34  	It("Test Application Validator [bad request]", func() {
    35  		req := admission.Request{
    36  			AdmissionRequest: admissionv1.AdmissionRequest{
    37  				Operation: admissionv1.Create,
    38  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
    39  				Object:    runtime.RawExtension{Raw: []byte("bad request")},
    40  			},
    41  		}
    42  		resp := handler.Handle(ctx, req)
    43  		Expect(resp.Allowed).Should(BeFalse())
    44  	})
    45  
    46  	It("Test Application Validator [Allow]", func() {
    47  		req := admission.Request{
    48  			AdmissionRequest: admissionv1.AdmissionRequest{
    49  				Operation: admissionv1.Create,
    50  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
    51  				Object: runtime.RawExtension{
    52  					Raw: []byte(`
    53  {"apiVersion":"core.oam.dev/v1beta1",
    54  "kind":"Application",
    55  "metadata":{"name":"application-sample"},
    56  "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"},
    57  "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}}
    58  `),
    59  				},
    60  			},
    61  		}
    62  		resp := handler.Handle(ctx, req)
    63  		Expect(resp.Allowed).Should(BeTrue())
    64  	})
    65  
    66  	It("Test Application Validator [Error]", func() {
    67  		req := admission.Request{
    68  			AdmissionRequest: admissionv1.AdmissionRequest{
    69  				Operation: admissionv1.Create,
    70  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
    71  				Object: runtime.RawExtension{
    72  					Raw: []byte(`{"apiVersion":"core.oam.dev/v1beta1",
    73  "kind":"Application",
    74  "metadata":{"name":"application-sample"},
    75  "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"},
    76  "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker1"}]}}`),
    77  				},
    78  			},
    79  		}
    80  		resp := handler.Handle(ctx, req)
    81  		Expect(resp.Allowed).Should(BeFalse())
    82  	})
    83  
    84  	It("Test Application Validator Forbid rollout annotation", func() {
    85  		req := admission.Request{
    86  			AdmissionRequest: admissionv1.AdmissionRequest{
    87  				Operation: admissionv1.Update,
    88  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
    89  				Object: runtime.RawExtension{
    90  					Raw: []byte(`
    91  {"apiVersion":"core.oam.dev/v1beta1",
    92  "kind":"Application",
    93  "metadata":{"name":"application-sample", "annotations": {"app.oam.dev/rollout" : "true"},}
    94  "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"},
    95  "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}}
    96  `),
    97  				},
    98  				OldObject: runtime.RawExtension{
    99  					Raw: []byte(`
   100  {"apiVersion":"core.oam.dev/v1beta1",
   101  "kind":"Application",
   102  "metadata":{"name":"application-sample"},
   103  "spec":{"components":[{"type":"myweb","properties":{"cmd":["sleep","1000"],"image":"busybox"},
   104  "traits":[{"type":"scaler","properties":{"replicas":10}}],"type":"worker"}]}}
   105  `),
   106  				},
   107  			},
   108  		}
   109  		resp := handler.Handle(ctx, req)
   110  		Expect(resp.Allowed).Should(BeFalse())
   111  	})
   112  
   113  	It("Test Application Validator workflow step name duplicate [error]", func() {
   114  		By("test duplicated step name in workflow")
   115  		req := admission.Request{
   116  			AdmissionRequest: admissionv1.AdmissionRequest{
   117  				Operation: admissionv1.Create,
   118  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
   119  				Object: runtime.RawExtension{
   120  					Raw: []byte(`
   121  {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"suspend","type":"suspend"},{"name":"suspend","type":"suspend"}]}}}
   122  `),
   123  				},
   124  			},
   125  		}
   126  		resp := handler.Handle(ctx, req)
   127  		Expect(resp.Allowed).Should(BeFalse())
   128  
   129  		By("test duplicated sub step name in workflow")
   130  		req = admission.Request{
   131  			AdmissionRequest: admissionv1.AdmissionRequest{
   132  				Operation: admissionv1.Create,
   133  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
   134  				Object: runtime.RawExtension{
   135  					Raw: []byte(`
   136  {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"step-group","subSteps":[{"name":"sub","type":"suspend"},{"name":"sub","type":"suspend"}]}]}}}
   137  `),
   138  				},
   139  			},
   140  		}
   141  		resp = handler.Handle(ctx, req)
   142  		Expect(resp.Allowed).Should(BeFalse())
   143  
   144  		By("test duplicated sub and parent step name in workflow")
   145  		req = admission.Request{
   146  			AdmissionRequest: admissionv1.AdmissionRequest{
   147  				Operation: admissionv1.Create,
   148  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
   149  				Object: runtime.RawExtension{
   150  					Raw: []byte(`
   151  {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-duplicate","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"step-group","subSteps":[{"name":"group","type":"suspend"},{"name":"sub","type":"suspend"}]}]}}}
   152  `),
   153  				},
   154  			},
   155  		}
   156  		resp = handler.Handle(ctx, req)
   157  		Expect(resp.Allowed).Should(BeFalse())
   158  	})
   159  
   160  	It("Test Application Validator workflow step invalid timeout [error]", func() {
   161  		req := admission.Request{
   162  			AdmissionRequest: admissionv1.AdmissionRequest{
   163  				Operation: admissionv1.Create,
   164  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
   165  				Object: runtime.RawExtension{
   166  					Raw: []byte(`
   167  {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"test"}]}}}
   168  `),
   169  				},
   170  			},
   171  		}
   172  		resp := handler.Handle(ctx, req)
   173  		Expect(resp.Allowed).Should(BeFalse())
   174  	})
   175  
   176  	It("Test Application Validator workflow step invalid timeout [allow]", func() {
   177  		req := admission.Request{
   178  			AdmissionRequest: admissionv1.AdmissionRequest{
   179  				Operation: admissionv1.Create,
   180  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1alpha2", Resource: "applications"},
   181  				Object: runtime.RawExtension{
   182  					Raw: []byte(`
   183  {"apiVersion":"core.oam.dev/v1beta1","kind":"Application","metadata":{"name":"workflow-timeout","namespace":"default"},"spec":{"components":[{"name":"comp","type":"worker","properties":{"image":"crccheck/hello-world"}}],"workflow":{"steps":[{"name":"group","type":"suspend","timeout":"1s"}]}}}
   184  `),
   185  				},
   186  			},
   187  		}
   188  		resp := handler.Handle(ctx, req)
   189  		Expect(resp.Allowed).Should(BeTrue())
   190  	})
   191  
   192  	It("Test Application with empty policy", func() {
   193  		req := admission.Request{
   194  			AdmissionRequest: admissionv1.AdmissionRequest{
   195  				Operation: admissionv1.Create,
   196  				Resource:  metav1.GroupVersionResource{Group: "core.oam.dev", Version: "v1beta1", Resource: "applications"},
   197  				Object: runtime.RawExtension{
   198  					Raw: []byte(`
   199  {"kind":"Application","metadata":{"name":"app-with-empty-policy-webhook-test", "namespace":"default"},
   200  "spec":{"components":[],"policies":[{"name":"2345","type":"garbage-collect","properties":null}]}}
   201  `),
   202  				},
   203  			},
   204  		}
   205  		resp := handler.Handle(ctx, req)
   206  		Expect(resp.Allowed).Should(BeFalse())
   207  	})
   208  })