Skip to content

Commit ffb233f

Browse files
authored
Merge pull request kubernetes#95155 from cmluciano/cml/netpolapie2e
netpol: Add CRUD tests for NetworkPolicy API
2 parents 161df49 + 62ac60c commit ffb233f

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

test/e2e/network/network_policy.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"net"
24+
"time"
2425

2526
v1 "k8s.io/api/core/v1"
2627
networkingv1 "k8s.io/api/networking/v1"
2728
apierrors "k8s.io/apimachinery/pkg/api/errors"
2829
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930
"k8s.io/apimachinery/pkg/types"
3031
"k8s.io/apimachinery/pkg/util/intstr"
32+
"k8s.io/apimachinery/pkg/util/wait"
33+
"k8s.io/apimachinery/pkg/watch"
3134
"k8s.io/kubernetes/test/e2e/framework"
3235
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
3336
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
@@ -2268,3 +2271,179 @@ func cleanupNetworkPolicy(f *framework.Framework, policy *networkingv1.NetworkPo
22682271
framework.Failf("unable to cleanup policy %v: %v", policy.Name, err)
22692272
}
22702273
}
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

Comments
 (0)