Skip to content

Commit a7264f9

Browse files
authored
pod terminationGracePeriodSeconds is always valid (kubernetes#124461)
* Pod terminationGracePeriodSeconds is always valid Validation of a pod spec will always use the pod's TerminationGracePeriodSeconds value. A set of pod test-helpers have been created to help construct Pods. * remove unused func * reduction * reduce 2 * simplify test * report invalid grace period * update SupplementalGroupPolicy tests
1 parent a9c156b commit a7264f9

File tree

22 files changed

+3114
-5535
lines changed

22 files changed

+3114
-5535
lines changed

pkg/api/pod/testing/make.go

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package testing
18+
19+
import (
20+
v1 "k8s.io/api/core/v1"
21+
"k8s.io/apimachinery/pkg/api/resource"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
api "k8s.io/kubernetes/pkg/apis/core"
24+
"k8s.io/utils/ptr"
25+
)
26+
27+
// Tweak is a function that modifies a Pod.
28+
type Tweak func(*api.Pod)
29+
type TweakContainer func(*api.Container)
30+
31+
// MakePod helps construct Pod objects (which pass API validation) more
32+
// legibly and tersely than a Go struct definition. By default this produces
33+
// a Pod with a single container, ctr. The caller can pass any number of tweak
34+
// functions to further modify the result.
35+
func MakePod(name string, tweaks ...Tweak) *api.Pod {
36+
// NOTE: Any field that would be populated by defaulting needs to be
37+
// present and valid here.
38+
pod := &api.Pod{
39+
ObjectMeta: metav1.ObjectMeta{
40+
Name: name,
41+
Namespace: metav1.NamespaceDefault,
42+
},
43+
Spec: api.PodSpec{
44+
Containers: []api.Container{MakeContainer("ctr")},
45+
DNSPolicy: api.DNSClusterFirst,
46+
RestartPolicy: api.RestartPolicyAlways,
47+
TerminationGracePeriodSeconds: ptr.To[int64](v1.DefaultTerminationGracePeriodSeconds),
48+
},
49+
}
50+
51+
for _, tweak := range tweaks {
52+
tweak(pod)
53+
}
54+
55+
return pod
56+
}
57+
58+
func MakePodSpec(policy api.RestartPolicy, tweaks ...Tweak) api.PodSpec {
59+
return MakePod("", append([]Tweak{SetRestartPolicy(policy)}, tweaks...)...).Spec
60+
}
61+
62+
func SetNamespace(ns string) Tweak {
63+
return func(pod *api.Pod) {
64+
pod.Namespace = ns
65+
}
66+
}
67+
68+
func SetResourceVersion(rv string) Tweak {
69+
return func(pod *api.Pod) {
70+
pod.ResourceVersion = rv
71+
}
72+
}
73+
74+
func SetContainers(containers ...api.Container) Tweak {
75+
return func(pod *api.Pod) {
76+
pod.Spec.Containers = containers
77+
}
78+
}
79+
80+
func SetInitContainers(containers ...api.Container) Tweak {
81+
return func(pod *api.Pod) {
82+
pod.Spec.InitContainers = containers
83+
}
84+
}
85+
86+
func SetEphemeralContainers(containers ...api.EphemeralContainer) Tweak {
87+
return func(pod *api.Pod) {
88+
pod.Spec.EphemeralContainers = containers
89+
}
90+
}
91+
92+
func SetVolumes(volumes ...api.Volume) Tweak {
93+
return func(pod *api.Pod) {
94+
pod.Spec.Volumes = volumes
95+
}
96+
}
97+
98+
func MakeEmptyVolume(name string) api.Volume {
99+
return api.Volume{Name: name, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}
100+
}
101+
102+
func SetNodeSelector(nodeSelector map[string]string) Tweak {
103+
return func(pod *api.Pod) {
104+
pod.Spec.NodeSelector = nodeSelector
105+
}
106+
}
107+
108+
func SetNodeName(name string) Tweak {
109+
return func(pod *api.Pod) {
110+
pod.Spec.NodeName = name
111+
}
112+
}
113+
114+
func SetActiveDeadlineSeconds(deadline int64) Tweak {
115+
return func(pod *api.Pod) {
116+
pod.Spec.ActiveDeadlineSeconds = &deadline
117+
}
118+
}
119+
120+
func SetServiceAccountName(name string) Tweak {
121+
return func(pod *api.Pod) {
122+
pod.Spec.ServiceAccountName = name
123+
}
124+
}
125+
126+
func SetSecurityContext(ctx *api.PodSecurityContext) Tweak {
127+
return func(pod *api.Pod) {
128+
pod.Spec.SecurityContext = ctx
129+
}
130+
}
131+
132+
func SetAffinity(affinity *api.Affinity) Tweak {
133+
return func(pod *api.Pod) {
134+
pod.Spec.Affinity = affinity
135+
}
136+
}
137+
138+
func SetHostAliases(hostAliases ...api.HostAlias) Tweak {
139+
return func(pod *api.Pod) {
140+
pod.Spec.HostAliases = hostAliases
141+
}
142+
}
143+
144+
func SetPriorityClassName(name string) Tweak {
145+
return func(pod *api.Pod) {
146+
pod.Spec.PriorityClassName = name
147+
}
148+
}
149+
150+
func SetRuntimeClassName(name string) Tweak {
151+
return func(pod *api.Pod) {
152+
pod.Spec.RuntimeClassName = &name
153+
}
154+
}
155+
156+
func SetOverhead(overhead api.ResourceList) Tweak {
157+
return func(pod *api.Pod) {
158+
pod.Spec.Overhead = overhead
159+
}
160+
}
161+
162+
func SetDNSPolicy(policy api.DNSPolicy) Tweak {
163+
return func(pod *api.Pod) {
164+
pod.Spec.DNSPolicy = policy
165+
}
166+
}
167+
168+
func SetRestartPolicy(policy api.RestartPolicy) Tweak {
169+
return func(pod *api.Pod) {
170+
pod.Spec.RestartPolicy = policy
171+
}
172+
}
173+
174+
func SetTolerations(tolerations ...api.Toleration) Tweak {
175+
return func(pod *api.Pod) {
176+
pod.Spec.Tolerations = tolerations
177+
}
178+
}
179+
180+
func SetAnnotations(annos map[string]string) Tweak {
181+
return func(pod *api.Pod) {
182+
pod.Annotations = annos
183+
}
184+
}
185+
186+
func SetLabels(annos map[string]string) Tweak {
187+
return func(pod *api.Pod) {
188+
pod.Labels = annos
189+
}
190+
}
191+
192+
func SetSchedulingGates(gates ...api.PodSchedulingGate) Tweak {
193+
return func(pod *api.Pod) {
194+
pod.Spec.SchedulingGates = gates
195+
}
196+
}
197+
198+
func SetTerminationGracePeriodSeconds(grace int64) Tweak {
199+
return func(pod *api.Pod) {
200+
pod.Spec.TerminationGracePeriodSeconds = &grace
201+
}
202+
}
203+
204+
func SetOS(name api.OSName) Tweak {
205+
return func(pod *api.Pod) {
206+
pod.Spec.OS = &api.PodOS{Name: name}
207+
}
208+
}
209+
210+
func SetStatus(status api.PodStatus) Tweak {
211+
return func(pod *api.Pod) {
212+
pod.Status = status
213+
}
214+
}
215+
216+
func SetResourceClaims(claims ...api.PodResourceClaim) Tweak {
217+
return func(pod *api.Pod) {
218+
pod.Spec.ResourceClaims = claims
219+
}
220+
}
221+
222+
func SetTopologySpreadConstraints(tsc ...api.TopologySpreadConstraint) Tweak {
223+
return func(pod *api.Pod) {
224+
pod.Spec.TopologySpreadConstraints = tsc
225+
}
226+
}
227+
228+
func SetObjectMeta(objectMeta metav1.ObjectMeta) Tweak {
229+
return func(pod *api.Pod) {
230+
pod.ObjectMeta = objectMeta
231+
}
232+
}
233+
234+
func MakeContainer(name string, tweaks ...TweakContainer) api.Container {
235+
cnr := api.Container{
236+
Name: name, Image: "image", ImagePullPolicy: "IfNotPresent",
237+
TerminationMessagePolicy: "File",
238+
TerminationMessagePath: v1.TerminationMessagePathDefault,
239+
}
240+
241+
for _, tweak := range tweaks {
242+
tweak(&cnr)
243+
}
244+
245+
return cnr
246+
}
247+
248+
func SetContainerImage(image string) TweakContainer {
249+
return func(cnr *api.Container) {
250+
cnr.Image = image
251+
}
252+
}
253+
254+
func MakeResourceRequirements(requests, limits map[string]string) api.ResourceRequirements {
255+
rr := api.ResourceRequirements{Requests: api.ResourceList{}, Limits: api.ResourceList{}}
256+
for k, v := range requests {
257+
rr.Requests[api.ResourceName(k)] = resource.MustParse(v)
258+
}
259+
for k, v := range limits {
260+
rr.Limits[api.ResourceName(k)] = resource.MustParse(v)
261+
}
262+
return rr
263+
}
264+
265+
func SetContainerResources(rr api.ResourceRequirements) TweakContainer {
266+
return func(cnr *api.Container) {
267+
cnr.Resources = rr
268+
}
269+
}
270+
271+
func SetContainerPorts(ports ...api.ContainerPort) TweakContainer {
272+
return func(cnr *api.Container) {
273+
cnr.Ports = ports
274+
}
275+
}
276+
277+
func SetContainerResizePolicy(policies ...api.ContainerResizePolicy) TweakContainer {
278+
return func(cnr *api.Container) {
279+
cnr.ResizePolicy = policies
280+
}
281+
}
282+
283+
func SetContainerSecurityContext(ctx api.SecurityContext) TweakContainer {
284+
return func(cnr *api.Container) {
285+
cnr.SecurityContext = &ctx
286+
}
287+
}
288+
289+
func SetContainerRestartPolicy(policy api.ContainerRestartPolicy) TweakContainer {
290+
return func(cnr *api.Container) {
291+
cnr.RestartPolicy = &policy
292+
}
293+
}

0 commit comments

Comments
 (0)