@@ -2132,16 +2132,30 @@ func Test_ValidatingAdmissionPolicy_ParamResourceDeletedThenRecreated(t *testing
2132
2132
}
2133
2133
}
2134
2134
2135
- // Test_CostLimitForValidation tests the cost limit set for a ValidatingAdmissionPolicy.
2135
+ // Test_CostLimitForValidation tests the cost limit set for a ValidatingAdmissionPolicy
2136
+ // with StrictCostEnforcementForVAP feature enabled.
2136
2137
func Test_CostLimitForValidation (t * testing.T ) {
2138
+ generic .PolicyRefreshInterval = 10 * time .Millisecond
2139
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , genericfeatures .StrictCostEnforcementForVAP , true )
2140
+ server , err := apiservertesting .StartTestServer (t , nil , []string {
2141
+ "--enable-admission-plugins" , "ValidatingAdmissionPolicy" ,
2142
+ }, framework .SharedEtcd ())
2143
+ if err != nil {
2144
+ t .Fatal (err )
2145
+ }
2146
+ defer server .TearDownFn ()
2147
+
2148
+ config := server .ClientConfig
2149
+ client , err := clientset .NewForConfig (config )
2150
+ if err != nil {
2151
+ t .Fatal (err )
2152
+ }
2153
+
2137
2154
testcases := []struct {
2138
- name string
2139
- policy * admissionregistrationv1.ValidatingAdmissionPolicy
2140
- policyBinding * admissionregistrationv1.ValidatingAdmissionPolicyBinding
2141
- namespace * v1.Namespace
2142
- err string
2143
- failureReason metav1.StatusReason
2144
- strictCostEnforcement bool
2155
+ name string
2156
+ policy * admissionregistrationv1.ValidatingAdmissionPolicy
2157
+ err string
2158
+ failureReason metav1.StatusReason
2145
2159
}{
2146
2160
{
2147
2161
name : "With StrictCostEnforcementForVAP: Single expression exceeds per call cost limit for native library" ,
@@ -2150,15 +2164,8 @@ func Test_CostLimitForValidation(t *testing.T) {
2150
2164
Expression : "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(x, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(y, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z5, int('1'.find('[0-9]*')) < 100)))))))" ,
2151
2165
},
2152
2166
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2153
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2154
- namespace : & v1.Namespace {
2155
- ObjectMeta : metav1.ObjectMeta {
2156
- Name : "test-k8s" ,
2157
- },
2158
- },
2159
- err : "operation cancelled: actual cost limit exceeded" ,
2160
- failureReason : metav1 .StatusReasonInvalid ,
2161
- strictCostEnforcement : true ,
2167
+ err : "operation cancelled: actual cost limit exceeded" ,
2168
+ failureReason : metav1 .StatusReasonInvalid ,
2162
2169
},
2163
2170
{
2164
2171
name : "With StrictCostEnforcementForVAP: Expression exceeds per call cost limit for extended library" ,
@@ -2168,15 +2175,8 @@ func Test_CostLimitForValidation(t *testing.T) {
2168
2175
Expression : "authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed() && authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed() && authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed()" ,
2169
2176
},
2170
2177
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2171
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2172
- namespace : & v1.Namespace {
2173
- ObjectMeta : metav1.ObjectMeta {
2174
- Name : "test-k8s" ,
2175
- },
2176
- },
2177
- err : "operation cancelled: actual cost limit exceeded" ,
2178
- failureReason : metav1 .StatusReasonInvalid ,
2179
- strictCostEnforcement : true ,
2178
+ err : "operation cancelled: actual cost limit exceeded" ,
2179
+ failureReason : metav1 .StatusReasonInvalid ,
2180
2180
},
2181
2181
{
2182
2182
name : "With StrictCostEnforcementForVAP: Expression exceeds per call cost limit for extended library in variables" ,
@@ -2190,15 +2190,8 @@ func Test_CostLimitForValidation(t *testing.T) {
2190
2190
Expression : "variables.authzCheck" ,
2191
2191
},
2192
2192
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" ))))),
2193
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2194
- namespace : & v1.Namespace {
2195
- ObjectMeta : metav1.ObjectMeta {
2196
- Name : "test-k8s" ,
2197
- },
2198
- },
2199
- err : "operation cancelled: actual cost limit exceeded" ,
2200
- failureReason : metav1 .StatusReasonInvalid ,
2201
- strictCostEnforcement : true ,
2193
+ err : "operation cancelled: actual cost limit exceeded" ,
2194
+ failureReason : metav1 .StatusReasonInvalid ,
2202
2195
},
2203
2196
{
2204
2197
name : "With StrictCostEnforcementForVAP: Expression exceeds per call cost limit for extended library in matchConditions" ,
@@ -2212,45 +2205,75 @@ func Test_CostLimitForValidation(t *testing.T) {
2212
2205
Expression : "true" ,
2213
2206
},
2214
2207
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" ))))),
2215
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2216
- namespace : & v1.Namespace {
2217
- ObjectMeta : metav1.ObjectMeta {
2218
- Name : "test-k8s" ,
2219
- },
2220
- },
2221
- err : "operation cancelled: actual cost limit exceeded" ,
2222
- failureReason : metav1 .StatusReasonInvalid ,
2223
- strictCostEnforcement : true ,
2208
+ err : "operation cancelled: actual cost limit exceeded" ,
2209
+ failureReason : metav1 .StatusReasonInvalid ,
2224
2210
},
2225
2211
{
2226
2212
name : "With StrictCostEnforcementForVAP: Expression exceeds per policy cost limit for extended library" ,
2227
2213
policy : withValidations (generateValidationsWithAuthzCheck (29 , "authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed()" ), withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2228
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2229
- namespace : & v1.Namespace {
2214
+ err : "validation failed due to running out of cost budget, no further validation rules will be run" ,
2215
+ failureReason : metav1 .StatusReasonInvalid ,
2216
+ },
2217
+ }
2218
+ for _ , testcase := range testcases {
2219
+ t .Run (testcase .name , func (t * testing.T ) {
2220
+ policy := withWaitReadyConstraintAndExpression (testcase .policy )
2221
+ if _ , err := client .AdmissionregistrationV1 ().ValidatingAdmissionPolicies ().Create (context .TODO (), policy , metav1.CreateOptions {}); err != nil {
2222
+ t .Fatal (err )
2223
+ }
2224
+ policyBinding := makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" )
2225
+ if err := createAndWaitReady (t , client , policyBinding , nil ); err != nil {
2226
+ t .Fatal (err )
2227
+ }
2228
+
2229
+ ns := & v1.Namespace {
2230
2230
ObjectMeta : metav1.ObjectMeta {
2231
2231
Name : "test-k8s" ,
2232
2232
},
2233
- },
2234
- err : "validation failed due to running out of cost budget, no further validation rules will be run" ,
2235
- failureReason : metav1 .StatusReasonInvalid ,
2236
- strictCostEnforcement : true ,
2237
- },
2233
+ }
2234
+ _ , err = client .CoreV1 ().Namespaces ().Create (context .TODO (), ns , metav1.CreateOptions {})
2235
+ checkExpectedError (t , err , testcase .err )
2236
+ checkFailureReason (t , err , testcase .failureReason )
2237
+ if err := cleanupPolicy (t , client , policy , policyBinding ); err != nil {
2238
+ t .Fatalf ("error while cleaning up policy and its bindings: %v" , err )
2239
+ }
2240
+ })
2241
+ }
2242
+ }
2243
+
2244
+ // Test_CostLimitForValidationWithFeatureDisabled tests the cost limit set for a ValidatingAdmissionPolicy
2245
+ // with StrictCostEnforcementForVAP feature disabled.
2246
+ func Test_CostLimitForValidationWithFeatureDisabled (t * testing.T ) {
2247
+ generic .PolicyRefreshInterval = 10 * time .Millisecond
2248
+ server , err := apiservertesting .StartTestServer (t , nil , []string {
2249
+ "--enable-admission-plugins" , "ValidatingAdmissionPolicy" ,
2250
+ }, framework .SharedEtcd ())
2251
+ if err != nil {
2252
+ t .Fatal (err )
2253
+ }
2254
+ defer server .TearDownFn ()
2255
+
2256
+ config := server .ClientConfig
2257
+ client , err := clientset .NewForConfig (config )
2258
+ if err != nil {
2259
+ t .Fatal (err )
2260
+ }
2261
+
2262
+ testcases := []struct {
2263
+ name string
2264
+ policy * admissionregistrationv1.ValidatingAdmissionPolicy
2265
+ err string
2266
+ failureReason metav1.StatusReason
2267
+ }{
2238
2268
{
2239
2269
name : "Without StrictCostEnforcementForVAP: Single expression exceeds per call cost limit for native library" ,
2240
2270
policy : withValidations ([]admissionregistrationv1.Validation {
2241
2271
{
2242
2272
Expression : "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(x, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(y, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].all(z5, int('1'.find('[0-9]*')) < 100)))))))" ,
2243
2273
},
2244
2274
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2245
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2246
- namespace : & v1.Namespace {
2247
- ObjectMeta : metav1.ObjectMeta {
2248
- Name : "test-k8s" ,
2249
- },
2250
- },
2251
- err : "operation cancelled: actual cost limit exceeded" ,
2252
- failureReason : metav1 .StatusReasonInvalid ,
2253
- strictCostEnforcement : false ,
2275
+ err : "operation cancelled: actual cost limit exceeded" ,
2276
+ failureReason : metav1 .StatusReasonInvalid ,
2254
2277
},
2255
2278
{
2256
2279
name : "Without StrictCostEnforcementForVAP: Expression does not exceed per call cost limit for extended library" ,
@@ -2260,13 +2283,6 @@ func Test_CostLimitForValidation(t *testing.T) {
2260
2283
Expression : "authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed() && authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed() && authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed()" ,
2261
2284
},
2262
2285
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2263
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2264
- namespace : & v1.Namespace {
2265
- ObjectMeta : metav1.ObjectMeta {
2266
- Name : "test-k8s" ,
2267
- },
2268
- },
2269
- strictCostEnforcement : false ,
2270
2286
},
2271
2287
{
2272
2288
name : "Without StrictCostEnforcementForVAP: Expression does not exceed per call cost limit for extended library in variables" ,
@@ -2280,56 +2296,36 @@ func Test_CostLimitForValidation(t *testing.T) {
2280
2296
Expression : "variables.authzCheck" ,
2281
2297
},
2282
2298
}, withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" ))))),
2283
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2284
- namespace : & v1.Namespace {
2285
- ObjectMeta : metav1.ObjectMeta {
2286
- Name : "test-k8s" ,
2287
- },
2288
- },
2289
- strictCostEnforcement : false ,
2290
2299
},
2291
2300
{
2292
- name : "Without StrictCostEnforcementForVAP: Expression does not exceed per policy cost limit for extended library" ,
2293
- policy : withValidations (generateValidationsWithAuthzCheck (29 , "authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed()" ), withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2294
- policyBinding : makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" ),
2295
- namespace : & v1.Namespace {
2296
- ObjectMeta : metav1.ObjectMeta {
2297
- Name : "test-k8s" ,
2298
- },
2299
- },
2300
- strictCostEnforcement : false ,
2301
+ name : "Without StrictCostEnforcementForVAP: Expression does not exceed per policy cost limit for extended library" ,
2302
+ policy : withValidations (generateValidationsWithAuthzCheck (29 , "authorizer.group('apps').resource('deployments').subresource('status').namespace('test').name('backend').check('create').allowed()" ), withFailurePolicy (admissionregistrationv1 .Fail , withNamespaceMatch (makePolicy ("validate-namespace-suffix" )))),
2301
2303
},
2302
2304
}
2303
- for _ , testcase := range testcases {
2305
+ for i , testcase := range testcases {
2304
2306
t .Run (testcase .name , func (t * testing.T ) {
2305
- featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , genericfeatures .StrictCostEnforcementForVAP , testcase .strictCostEnforcement )
2306
-
2307
- server , err := apiservertesting .StartTestServer (t , nil , []string {
2308
- "--enable-admission-plugins" , "ValidatingAdmissionPolicy" ,
2309
- }, framework .SharedEtcd ())
2310
- if err != nil {
2311
- t .Fatal (err )
2312
- }
2313
- defer server .TearDownFn ()
2314
-
2315
- config := server .ClientConfig
2316
-
2317
- client , err := clientset .NewForConfig (config )
2318
- if err != nil {
2319
- t .Fatal (err )
2320
- }
2321
2307
policy := withWaitReadyConstraintAndExpression (testcase .policy )
2322
2308
if _ , err := client .AdmissionregistrationV1 ().ValidatingAdmissionPolicies ().Create (context .TODO (), policy , metav1.CreateOptions {}); err != nil {
2323
2309
t .Fatal (err )
2324
2310
}
2325
- if err := createAndWaitReady (t , client , testcase .policyBinding , nil ); err != nil {
2311
+ policyBinding := makeBinding ("validate-namespace-suffix-binding" , "validate-namespace-suffix" , "" )
2312
+ if err := createAndWaitReady (t , client , policyBinding , nil ); err != nil {
2326
2313
t .Fatal (err )
2327
2314
}
2328
2315
2329
- _ , err = client .CoreV1 ().Namespaces ().Create (context .TODO (), testcase .namespace , metav1.CreateOptions {})
2316
+ nsName := fmt .Sprintf ("test-%d-k8s" , i )
2317
+ ns := & v1.Namespace {
2318
+ ObjectMeta : metav1.ObjectMeta {
2319
+ Name : nsName ,
2320
+ },
2321
+ }
2330
2322
2323
+ _ , err = client .CoreV1 ().Namespaces ().Create (context .TODO (), ns , metav1.CreateOptions {})
2331
2324
checkExpectedError (t , err , testcase .err )
2332
2325
checkFailureReason (t , err , testcase .failureReason )
2326
+ if err := cleanupPolicy (t , client , policy , policyBinding ); err != nil {
2327
+ t .Fatalf ("error while cleaning up policy and its bindings: %v" , err )
2328
+ }
2333
2329
})
2334
2330
}
2335
2331
}
0 commit comments