...
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
17set -o errexit
18set -o nounset
19set -o pipefail
20
21# Runs tests for kubectl diff
22run_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
121apiVersion: v1
122kind: Pod
123metadata:
124 name: a
125 namespace: nsbprune
126 labels:
127 prune-group: "true"
128spec:
129 containers:
130 - name: kubernetes-pause
131 image: registry.k8s.io/pause:3.9
132---
133apiVersion: v1
134kind: Pod
135metadata:
136 name: b
137 namespace: nsbprune
138 labels:
139 prune-group: "true"
140spec:
141 containers:
142 - name: kubernetes-pause
143 image: registry.k8s.io/pause:3.9
144---
145apiVersion: v1
146kind: Pod
147metadata:
148 name: c
149 namespace: nsbprune
150 labels:
151 prune-group: "false"
152spec:
153 containers:
154 - name: kubernetes-pause
155 image: registry.k8s.io/pause:3.9
156EOF
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
162apiVersion: v1
163kind: Pod
164metadata:
165 name: a
166 namespace: nsbprune
167 labels:
168 prune-group: "true"
169spec:
170 containers:
171 - name: kubernetes-pause
172 image: registry.k8s.io/pause:3.9
173---
174apiVersion: v1
175kind: Pod
176metadata:
177 name: c
178 namespace: nsbprune
179 labels:
180 prune-group: "false"
181spec:
182 containers:
183 - name: kubernetes-pause
184 image: registry.k8s.io/pause:3.9
185EOF
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
204run_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}
View as plain text