@@ -21,13 +21,16 @@ import (
21
21
"encoding/json"
22
22
"fmt"
23
23
"net"
24
+ "time"
24
25
25
26
v1 "k8s.io/api/core/v1"
26
27
networkingv1 "k8s.io/api/networking/v1"
27
28
apierrors "k8s.io/apimachinery/pkg/api/errors"
28
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
30
"k8s.io/apimachinery/pkg/types"
30
31
"k8s.io/apimachinery/pkg/util/intstr"
32
+ "k8s.io/apimachinery/pkg/util/wait"
33
+ "k8s.io/apimachinery/pkg/watch"
31
34
"k8s.io/kubernetes/test/e2e/framework"
32
35
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
33
36
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
@@ -2266,3 +2269,179 @@ func cleanupNetworkPolicy(f *framework.Framework, policy *networkingv1.NetworkPo
2266
2269
framework .Failf ("unable to cleanup policy %v: %v" , policy .Name , err )
2267
2270
}
2268
2271
}
2272
+
2273
+ var _ = SIGDescribe ("NetworkPolicy API" , func () {
2274
+ f := framework .NewDefaultFramework ("networkpolicies" )
2275
+ /*
2276
+ Release: v1.20
2277
+ Testname: NetworkPolicies API
2278
+ Description:
2279
+ - The networking.k8s.io API group MUST exist in the /apis discovery document.
2280
+ - The networking.k8s.io/v1 API group/version MUST exist in the /apis/networking.k8s.io discovery document.
2281
+ - The NetworkPolicies resources MUST exist in the /apis/networking.k8s.io/v1 discovery document.
2282
+ - The NetworkPolicies resource must support create, get, list, watch, update, patch, delete, and deletecollection.
2283
+ */
2284
+
2285
+ ginkgo .It ("should support creating NetworkPolicy API operations" , func () {
2286
+ // Setup
2287
+ ns := f .Namespace .Name
2288
+ npVersion := "v1"
2289
+ npClient := f .ClientSet .NetworkingV1 ().NetworkPolicies (ns )
2290
+ npTemplate := & networkingv1.NetworkPolicy {
2291
+ ObjectMeta : metav1.ObjectMeta {GenerateName : "e2e-example-netpol" ,
2292
+ Labels : map [string ]string {
2293
+ "special-label" : f .UniqueName ,
2294
+ }},
2295
+ Spec : networkingv1.NetworkPolicySpec {
2296
+ // Apply this policy to the Server
2297
+ PodSelector : metav1.LabelSelector {
2298
+ MatchLabels : map [string ]string {
2299
+ "pod-name" : "test-pod" ,
2300
+ },
2301
+ },
2302
+ // Allow traffic only from client-a in namespace-b
2303
+ Ingress : []networkingv1.NetworkPolicyIngressRule {{
2304
+ From : []networkingv1.NetworkPolicyPeer {{
2305
+ NamespaceSelector : & metav1.LabelSelector {
2306
+ MatchLabels : map [string ]string {
2307
+ "ns-name" : "pod-b" ,
2308
+ },
2309
+ },
2310
+ PodSelector : & metav1.LabelSelector {
2311
+ MatchLabels : map [string ]string {
2312
+ "pod-name" : "client-a" ,
2313
+ },
2314
+ },
2315
+ }},
2316
+ }},
2317
+ },
2318
+ }
2319
+ // Discovery
2320
+ ginkgo .By ("getting /apis" )
2321
+ {
2322
+ discoveryGroups , err := f .ClientSet .Discovery ().ServerGroups ()
2323
+ framework .ExpectNoError (err )
2324
+ found := false
2325
+ for _ , group := range discoveryGroups .Groups {
2326
+ if group .Name == networkingv1 .GroupName {
2327
+ for _ , version := range group .Versions {
2328
+ if version .Version == npVersion {
2329
+ found = true
2330
+ break
2331
+ }
2332
+ }
2333
+ }
2334
+ }
2335
+ framework .ExpectEqual (found , true , fmt .Sprintf ("expected networking API group/version, got %#v" , discoveryGroups .Groups ))
2336
+ }
2337
+ ginkgo .By ("getting /apis/networking.k8s.io" )
2338
+ {
2339
+ group := & metav1.APIGroup {}
2340
+ err := f .ClientSet .Discovery ().RESTClient ().Get ().AbsPath ("/apis/networking.k8s.io" ).Do (context .TODO ()).Into (group )
2341
+ framework .ExpectNoError (err )
2342
+ found := false
2343
+ for _ , version := range group .Versions {
2344
+ if version .Version == npVersion {
2345
+ found = true
2346
+ break
2347
+ }
2348
+ }
2349
+ framework .ExpectEqual (found , true , fmt .Sprintf ("expected networking API version, got %#v" , group .Versions ))
2350
+ }
2351
+ ginkgo .By ("getting /apis/networking.k8s.io" + npVersion )
2352
+ {
2353
+ resources , err := f .ClientSet .Discovery ().ServerResourcesForGroupVersion (networkingv1 .SchemeGroupVersion .String ())
2354
+ framework .ExpectNoError (err )
2355
+ foundNetPol := false
2356
+ for _ , resource := range resources .APIResources {
2357
+ switch resource .Name {
2358
+ case "networkpolicies" :
2359
+ foundNetPol = true
2360
+ }
2361
+ }
2362
+ framework .ExpectEqual (foundNetPol , true , fmt .Sprintf ("expected networkpolicies, got %#v" , resources .APIResources ))
2363
+ }
2364
+ // NetPol resource create/read/update/watch verbs
2365
+ ginkgo .By ("creating" )
2366
+ _ , err := npClient .Create (context .TODO (), npTemplate , metav1.CreateOptions {})
2367
+ framework .ExpectNoError (err )
2368
+ _ , err = npClient .Create (context .TODO (), npTemplate , metav1.CreateOptions {})
2369
+ framework .ExpectNoError (err )
2370
+ createdNetPol , err := npClient .Create (context .TODO (), npTemplate , metav1.CreateOptions {})
2371
+ framework .ExpectNoError (err )
2372
+
2373
+ ginkgo .By ("getting" )
2374
+ gottenNetPol , err := npClient .Get (context .TODO (), createdNetPol .Name , metav1.GetOptions {})
2375
+ framework .ExpectNoError (err )
2376
+ framework .ExpectEqual (gottenNetPol .UID , createdNetPol .UID )
2377
+
2378
+ ginkgo .By ("listing" )
2379
+ nps , err := npClient .List (context .TODO (), metav1.ListOptions {LabelSelector : "special-label=" + f .UniqueName })
2380
+ framework .ExpectNoError (err )
2381
+ framework .ExpectEqual (len (nps .Items ), 3 , "filtered list should have 3 items" )
2382
+
2383
+ ginkgo .By ("watching" )
2384
+ framework .Logf ("starting watch" )
2385
+ npWatch , err := npClient .Watch (context .TODO (), metav1.ListOptions {ResourceVersion : nps .ResourceVersion , LabelSelector : "special-label=" + f .UniqueName })
2386
+ framework .ExpectNoError (err )
2387
+ // Test cluster-wide list and watch
2388
+ clusterNPClient := f .ClientSet .NetworkingV1 ().NetworkPolicies ("" )
2389
+ ginkgo .By ("cluster-wide listing" )
2390
+ clusterNPs , err := clusterNPClient .List (context .TODO (), metav1.ListOptions {LabelSelector : "special-label=" + f .UniqueName })
2391
+ framework .ExpectNoError (err )
2392
+ framework .ExpectEqual (len (clusterNPs .Items ), 3 , "filtered list should have 3 items" )
2393
+
2394
+ ginkgo .By ("cluster-wide watching" )
2395
+ framework .Logf ("starting watch" )
2396
+ _ , err = clusterNPClient .Watch (context .TODO (), metav1.ListOptions {ResourceVersion : nps .ResourceVersion , LabelSelector : "special-label=" + f .UniqueName })
2397
+ framework .ExpectNoError (err )
2398
+
2399
+ ginkgo .By ("patching" )
2400
+ patchedNetPols , err := npClient .Patch (context .TODO (), createdNetPol .Name , types .MergePatchType , []byte (`{"metadata":{"annotations":{"patched":"true"}}}` ), metav1.PatchOptions {})
2401
+ framework .ExpectNoError (err )
2402
+ framework .ExpectEqual (patchedNetPols .Annotations ["patched" ], "true" , "patched object should have the applied annotation" )
2403
+
2404
+ ginkgo .By ("updating" )
2405
+ npToUpdate := patchedNetPols .DeepCopy ()
2406
+ npToUpdate .Annotations ["updated" ] = "true"
2407
+ updatedNetPols , err := npClient .Update (context .TODO (), npToUpdate , metav1.UpdateOptions {})
2408
+ framework .ExpectNoError (err )
2409
+ framework .ExpectEqual (updatedNetPols .Annotations ["updated" ], "true" , "updated object should have the applied annotation" )
2410
+
2411
+ framework .Logf ("waiting for watch events with expected annotations" )
2412
+ for sawAnnotations := false ; ! sawAnnotations ; {
2413
+ select {
2414
+ case evt , ok := <- npWatch .ResultChan ():
2415
+ framework .ExpectEqual (ok , true , "watch channel should not close" )
2416
+ framework .ExpectEqual (evt .Type , watch .Modified )
2417
+ watchedNetPol , isNetPol := evt .Object .(* networkingv1.NetworkPolicy )
2418
+ framework .ExpectEqual (isNetPol , true , fmt .Sprintf ("expected NetworkPolicy, got %T" , evt .Object ))
2419
+ if watchedNetPol .Annotations ["patched" ] == "true" && watchedNetPol .Annotations ["updated" ] == "true" {
2420
+ framework .Logf ("saw patched and updated annotations" )
2421
+ sawAnnotations = true
2422
+ npWatch .Stop ()
2423
+ } else {
2424
+ framework .Logf ("missing expected annotations, waiting: %#v" , watchedNetPol .Annotations )
2425
+ }
2426
+ case <- time .After (wait .ForeverTestTimeout ):
2427
+ framework .Fail ("timed out waiting for watch event" )
2428
+ }
2429
+ }
2430
+ // NetPol resource delete operations
2431
+ ginkgo .By ("deleting" )
2432
+ err = npClient .Delete (context .TODO (), createdNetPol .Name , metav1.DeleteOptions {})
2433
+ framework .ExpectNoError (err )
2434
+ _ , err = npClient .Get (context .TODO (), createdNetPol .Name , metav1.GetOptions {})
2435
+ framework .ExpectEqual (apierrors .IsNotFound (err ), true , fmt .Sprintf ("expected 404, got %#v" , err ))
2436
+ nps , err = npClient .List (context .TODO (), metav1.ListOptions {LabelSelector : "special-label=" + f .UniqueName })
2437
+ framework .ExpectNoError (err )
2438
+ framework .ExpectEqual (len (nps .Items ), 2 , "filtered list should have 2 items" )
2439
+
2440
+ ginkgo .By ("deleting a collection" )
2441
+ err = npClient .DeleteCollection (context .TODO (), metav1.DeleteOptions {}, metav1.ListOptions {LabelSelector : "special-label=" + f .UniqueName })
2442
+ framework .ExpectNoError (err )
2443
+ nps , err = npClient .List (context .TODO (), metav1.ListOptions {LabelSelector : "special-label=" + f .UniqueName })
2444
+ framework .ExpectNoError (err )
2445
+ framework .ExpectEqual (len (nps .Items ), 0 , "filtered list should have 0 items" )
2446
+ })
2447
+ })
0 commit comments