k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/cmd/diff.sh (about) 1 #!/usr/bin/env bash 2 3 # Copyright 2018 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 set -o errexit 18 set -o nounset 19 set -o pipefail 20 21 # Runs tests for kubectl diff 22 run_kubectl_diff_tests() { 23 set -o nounset 24 set -o errexit 25 26 create_and_use_new_namespace 27 kube::log::status "Testing kubectl diff" 28 29 # Test that it works when the live object doesn't exist 30 output_message=$(! kubectl diff -f hack/testdata/pod.yaml) 31 kube::test::if_has_string "${output_message}" 'test-pod' 32 # Ensure diff only dry-runs and doesn't persist change 33 kube::test::get_object_assert 'pod' "{{range.items}}{{ if eq ${id_field:?} \"test-pod\" }}found{{end}}{{end}}:" ':' 34 35 kubectl apply -f hack/testdata/pod.yaml 36 kube::test::get_object_assert 'pod' "{{range.items}}{{ if eq ${id_field:?} \"test-pod\" }}found{{end}}{{end}}:" 'found:' 37 initialResourceVersion=$(kubectl get "${kube_flags[@]:?}" -f hack/testdata/pod.yaml -o go-template='{{ .metadata.resourceVersion }}') 38 39 # Make sure that diffing the resource right after returns nothing (0 exit code). 40 kubectl diff -f hack/testdata/pod.yaml 41 42 # Ensure diff only dry-runs and doesn't persist change 43 resourceVersion=$(kubectl get "${kube_flags[@]:?}" -f hack/testdata/pod.yaml -o go-template='{{ .metadata.resourceVersion }}') 44 kube::test::if_has_string "${resourceVersion}" "${initialResourceVersion}" 45 46 # Make sure that: 47 # 1. the exit code for diff is 1 because it found a difference 48 # 2. the difference contains the changed image 49 # 3. the output doesn't indicate this is an error 50 output_message=$(kubectl diff -f hack/testdata/pod-changed.yaml 2>&1 || test $? -eq 1) 51 kube::test::if_has_string "${output_message}" 'registry.k8s.io/pause:3.4' 52 kube::test::if_has_not_string "${output_message}" 'exit status 1' 53 54 # Ensure diff only dry-runs and doesn't persist change 55 resourceVersion=$(kubectl get "${kube_flags[@]:?}" -f hack/testdata/pod.yaml -o go-template='{{ .metadata.resourceVersion }}') 56 kube::test::if_has_string "${resourceVersion}" "${initialResourceVersion}" 57 58 # Test found diff with server-side apply 59 output_message=$(kubectl diff -f hack/testdata/pod-changed.yaml --server-side || test $? -eq 1) 60 kube::test::if_has_string "${output_message}" 'registry.k8s.io/pause:3.4' 61 62 # Ensure diff --server-side only dry-runs and doesn't persist change 63 resourceVersion=$(kubectl get "${kube_flags[@]:?}" -f hack/testdata/pod.yaml -o go-template='{{ .metadata.resourceVersion }}') 64 kube::test::if_has_string "${resourceVersion}" "${initialResourceVersion}" 65 66 # Test that we have a return code bigger than 1 if there is an error when diffing 67 kubectl diff -f hack/testdata/invalid-pod.yaml || test $? -gt 1 68 69 # Cleanup 70 kubectl delete -f hack/testdata/pod.yaml 71 72 kube::log::status "Testing kubectl diff with server-side apply" 73 74 # Test that kubectl diff --server-side works when the live object doesn't exist 75 output_message=$(! kubectl diff --server-side -f hack/testdata/pod.yaml) 76 kube::test::if_has_string "${output_message}" 'test-pod' 77 # Ensure diff --server-side only dry-runs and doesn't persist change 78 kube::test::get_object_assert 'pod' "{{range.items}}{{ if eq ${id_field:?} \"test-pod\" }}found{{end}}{{end}}:" ':' 79 80 # Server-side apply the Pod 81 kubectl apply --server-side -f hack/testdata/pod.yaml 82 kube::test::get_object_assert 'pod' "{{range.items}}{{ if eq ${id_field:?} \"test-pod\" }}found{{end}}{{end}}:" 'found:' 83 84 # Make sure that --server-side diffing the resource right after returns nothing (0 exit code). 85 kubectl diff --server-side -f hack/testdata/pod.yaml 86 87 # Make sure that for kubectl diff --server-side: 88 # 1. the exit code for diff is 1 because it found a difference 89 # 2. the difference contains the changed image 90 output_message=$(kubectl diff --server-side -f hack/testdata/pod-changed.yaml || test $? -eq 1) 91 kube::test::if_has_string "${output_message}" 'registry.k8s.io/pause:3.4' 92 93 ## kubectl diff --prune 94 kubectl create ns nsb 95 kubectl apply --namespace nsb -l prune-group=true -f hack/testdata/prune/a.yaml 96 kube::test::get_object_assert 'pods a -n nsb' "{{${id_field:?}}}" 'a' 97 # Make sure that kubectl diff does not return pod 'a' without prune flag 98 output_message=$(kubectl diff -l prune-group=true -f hack/testdata/prune/b.yaml || test $? -eq 1) 99 kube::test::if_has_not_string "${output_message}" "name: a" 100 # Make sure that for kubectl diff --prune: 101 # 1. the exit code for diff is 1 because it found a difference 102 # 2. the difference contains the pruned pod 103 output_message=$(kubectl diff --prune -l prune-group=true -f hack/testdata/prune/b.yaml || test $? -eq 1) 104 # pod 'a' should be in output, it is pruned 105 kube::test::if_has_string "${output_message}" 'name: a' 106 # apply b with namespace 107 kubectl apply --prune --namespace nsb -l prune-group=true -f hack/testdata/prune/b.yaml 108 # check right pod exists and wrong pod doesn't exist 109 kube::test::wait_object_assert 'pods -n nsb' "{{range.items}}{{${id_field:?}}}:{{end}}" 'b:' 110 # Make sure that diff --prune returns nothing (0 exit code) for 'b'. 111 kubectl diff --prune -l prune-group=true -f hack/testdata/prune/b.yaml 112 113 # Cleanup 114 kubectl delete -f hack/testdata/pod.yaml 115 kubectl delete -f hack/testdata/prune/b.yaml 116 kubectl delete namespace nsb 117 118 ## kubectl diff --prune with label selector 119 kubectl create ns nsbprune 120 kubectl apply --namespace nsbprune -f - <<EOF 121 apiVersion: v1 122 kind: Pod 123 metadata: 124 name: a 125 namespace: nsbprune 126 labels: 127 prune-group: "true" 128 spec: 129 containers: 130 - name: kubernetes-pause 131 image: registry.k8s.io/pause:3.9 132 --- 133 apiVersion: v1 134 kind: Pod 135 metadata: 136 name: b 137 namespace: nsbprune 138 labels: 139 prune-group: "true" 140 spec: 141 containers: 142 - name: kubernetes-pause 143 image: registry.k8s.io/pause:3.9 144 --- 145 apiVersion: v1 146 kind: Pod 147 metadata: 148 name: c 149 namespace: nsbprune 150 labels: 151 prune-group: "false" 152 spec: 153 containers: 154 - name: kubernetes-pause 155 image: registry.k8s.io/pause:3.9 156 EOF 157 kube::test::get_object_assert 'pods a -n nsbprune' "{{${id_field:?}}}" 'a' 158 kube::test::get_object_assert 'pods b -n nsbprune' "{{${id_field:?}}}" 'b' 159 kube::test::get_object_assert 'pods c -n nsbprune' "{{${id_field:?}}}" 'c' 160 # Make sure that kubectl diff does not return either pod 'b' or pod 'c' without prune flag 161 PRUNE=$(cat <<EOF 162 apiVersion: v1 163 kind: Pod 164 metadata: 165 name: a 166 namespace: nsbprune 167 labels: 168 prune-group: "true" 169 spec: 170 containers: 171 - name: kubernetes-pause 172 image: registry.k8s.io/pause:3.9 173 --- 174 apiVersion: v1 175 kind: Pod 176 metadata: 177 name: c 178 namespace: nsbprune 179 labels: 180 prune-group: "false" 181 spec: 182 containers: 183 - name: kubernetes-pause 184 image: registry.k8s.io/pause:3.9 185 EOF 186 ) 187 output_message=$(echo "${PRUNE}" | kubectl diff -l prune-group=true -f -) 188 kube::test::if_has_not_string "${output_message}" "name: b" 189 kube::test::if_has_not_string "${output_message}" "name: c" 190 # the exit code for diff is 1 because pod 'b' is found in the given label selector but not 'c' 191 output_message=$(echo "${PRUNE}" | kubectl diff --prune -l prune-group=true -f - || test $? -eq 1) 192 # pod 'b' should be in output, it is pruned. On the other hand, 'c' should not be, it's label selector is different 193 kube::test::if_has_string "${output_message}" 'name: b' 194 kube::test::if_has_not_string "${output_message}" "name: c" 195 196 # Cleanup 197 kubectl delete namespace nsbprune 198 199 200 set +o nounset 201 set +o errexit 202 } 203 204 run_kubectl_diff_same_names() { 205 set -o nounset 206 set -o errexit 207 208 create_and_use_new_namespace 209 kube::log::status "Test kubectl diff with multiple resources with the same name" 210 211 output_message=$(KUBECTL_EXTERNAL_DIFF="find" kubectl diff -Rf hack/testdata/diff/) 212 kube::test::if_has_string "${output_message}" 'v1\.Pod\..*\.test' 213 kube::test::if_has_string "${output_message}" 'apps\.v1\.Deployment\..*\.test' 214 kube::test::if_has_string "${output_message}" 'v1\.ConfigMap\..*\.test' 215 kube::test::if_has_string "${output_message}" 'v1\.Secret\..*\.test' 216 217 set +o nounset 218 set +o errexit 219 }