Change:
I tried to update the NetworkPolicy Spec field with more ingress rules but got It seems NetworkPolicy does not allow update on Spec This means if I want to have more ingress rules, I will have to add those in a new networkpolicy in the same namespace. Any reason why I should not add those in the existing one(update the existing networkpolicy)? Thanks!
This is as designed for now. The expectation is that updates to the spec will be allowed when the NetworkPolicy API moves from v1beta1 to GA.
(And that is planned for Kubernetes 1.6 release.)
good to know, thanks!
Note that the PR to move NetworkPolicy to v1 did not make it into v1.6, but is now planned for 1.7:
Oh, I didn't know about this bug and that didn't get changed in but we can do it as another PR after. (I'm trying to not make any more changes there so we can get it merged.)

Discussion:
package validation import ( <del> "reflect" </del> unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation"

func ValidateNetworkPolicyUpdate(update, old *networking.NetworkPolicy) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata"))...) <del> if !reflect.DeepEqual(update.Spec, old.Spec) { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to networkpolicy spec are forbidden.")) } </del> <ins> allErrs = append(allErrs, ValidateNetworkPolicySpec(&update.Spec, field.NewPath("spec"))...) </ins> return allErrs }

old    networking.NetworkPolicy update networking.NetworkPolicy } <del> successCases := []npUpdateTest{ { </del> <ins> successCases := map[string]npUpdateTest{ "no change": { </ins> old: networking.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: networking.NetworkPolicySpec{

}, }, }, <del> } for _, successCase := range successCases { successCase.old.ObjectMeta.ResourceVersion = "1" successCase.update.ObjectMeta.ResourceVersion = "1" if errs := ValidateNetworkPolicyUpdate(&successCase.update, &successCase.old); len(errs) != 0 { t.Errorf("expected success: %v", errs) } } errorCases := map[string]npUpdateTest{ "change name": { </del> <ins> "change spec": { </ins> old: networking.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: networking.NetworkPolicySpec{

}, }, update: networking.NetworkPolicy{ <del> ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "bar"}, </del> <ins> ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, </ins> Spec: networking.NetworkPolicySpec{ <del> PodSelector: metav1.LabelSelector{}, Ingress:     []networking.NetworkPolicyIngressRule{}, </del> <ins> PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{"a": "b"}, }, Ingress: []networking.NetworkPolicyIngressRule{}, </ins> }, }, }, <del> "change spec": { </del> <ins> } for testName, successCase := range successCases { successCase.old.ObjectMeta.ResourceVersion = "1" successCase.update.ObjectMeta.ResourceVersion = "1" if errs := ValidateNetworkPolicyUpdate(&successCase.update, &successCase.old); len(errs) != 0 { t.Errorf("expected success (%s): %v", testName, errs) } } errorCases := map[string]npUpdateTest{ "change name": { </ins> old: networking.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: networking.NetworkPolicySpec{

}, }, update: networking.NetworkPolicy{ <del> ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, </del> <ins> ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "bar"}, </ins> Spec: networking.NetworkPolicySpec{ <del> PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{"a": "b"}, }, Ingress: []networking.NetworkPolicyIngressRule{}, </del> <ins> PodSelector: metav1.LabelSelector{}, Ingress:     []networking.NetworkPolicyIngressRule{}, </ins> }, }, }, } for testName, errorCase := range errorCases { <ins> errorCase.old.ObjectMeta.ResourceVersion = "1" errorCase.update.ObjectMeta.ResourceVersion = "1" </ins> if errs := ValidateNetworkPolicyUpdate(&errorCase.update, &errorCase.old); len(errs) == 0 { t.Errorf("expected failure: %s", testName) }