diff --git a/hack/testdata/service-revision1.yaml b/hack/testdata/service-revision1.yaml new file mode 100644 index 0000000000..2e5a5ceef3 --- /dev/null +++ b/hack/testdata/service-revision1.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Service +metadata: + name: a +spec: + selector: + app: test + clusterIP: None + ports: + - port: 80 diff --git a/hack/testdata/service-revision2.yaml b/hack/testdata/service-revision2.yaml new file mode 100644 index 0000000000..42da96a80d --- /dev/null +++ b/hack/testdata/service-revision2.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Service +metadata: + name: a +spec: + selector: + app: test + clusterIP: 10.0.0.12 + ports: + - port: 80 diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index 976915a450..9b72fcc9d0 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -753,7 +753,7 @@ func (p *patcher) patch(current runtime.Object, modified []byte, source, namespa } patchBytes, patchObject, err = p.patchSimple(current, modified, source, namespace, name, errOut) } - if err != nil && errors.IsConflict(err) && p.force { + if err != nil && (errors.IsConflict(err) || errors.IsInvalid(err)) && p.force { patchBytes, patchObject, err = p.deleteAndCreate(current, modified, namespace, name) } return patchBytes, patchObject, err diff --git a/test/cmd/apply.sh b/test/cmd/apply.sh index eaebf72b08..1e90f85300 100755 --- a/test/cmd/apply.sh +++ b/test/cmd/apply.sh @@ -157,6 +157,25 @@ run_kubectl_apply_tests() { # cleanup kubectl delete svc prune-svc 2>&1 "${kube_flags[@]}" + + ## kubectl apply -f some.yml --force + # Pre-condition: no service exists + kube::test::get_object_assert services "{{range.items}}{{$id_field}}:{{end}}" '' + # apply service a + kubectl apply -f hack/testdata/service-revision1.yaml "${kube_flags[@]}" + # check right service exists + kube::test::get_object_assert 'services a' "{{${id_field}}}" 'a' + # change immutable field and apply service a + output_message=$(! kubectl apply -f hack/testdata/service-revision2.yaml 2>&1 "${kube_flags[@]}") + kube::test::if_has_string "${output_message}" 'field is immutable' + # apply --force to recreate resources for immutable fields + kubectl apply -f hack/testdata/service-revision2.yaml --force "${kube_flags[@]}" + # check immutable field exists + kube::test::get_object_assert 'services a' "{{.spec.clusterIP}}" '10.0.0.12' + # cleanup + kubectl delete -f hack/testdata/service-revision2.yaml "${kube_flags[@]}" + + set +o nounset set +o errexit }