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