kubernetes/pkg/scheduler/testing/wrappers.go

698 lines
23 KiB
Go

/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"fmt"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
imageutils "k8s.io/kubernetes/test/utils/image"
"k8s.io/utils/pointer"
)
var zero int64
// NodeSelectorWrapper wraps a NodeSelector inside.
type NodeSelectorWrapper struct{ v1.NodeSelector }
// MakeNodeSelector creates a NodeSelector wrapper.
func MakeNodeSelector() *NodeSelectorWrapper {
return &NodeSelectorWrapper{v1.NodeSelector{}}
}
// In injects a matchExpression (with an operator IN) as a selectorTerm
// to the inner nodeSelector.
// NOTE: appended selecterTerms are ORed.
func (s *NodeSelectorWrapper) In(key string, vals []string) *NodeSelectorWrapper {
expression := v1.NodeSelectorRequirement{
Key: key,
Operator: v1.NodeSelectorOpIn,
Values: vals,
}
selectorTerm := v1.NodeSelectorTerm{}
selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression)
s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm)
return s
}
// NotIn injects a matchExpression (with an operator NotIn) as a selectorTerm
// to the inner nodeSelector.
func (s *NodeSelectorWrapper) NotIn(key string, vals []string) *NodeSelectorWrapper {
expression := v1.NodeSelectorRequirement{
Key: key,
Operator: v1.NodeSelectorOpNotIn,
Values: vals,
}
selectorTerm := v1.NodeSelectorTerm{}
selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression)
s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm)
return s
}
// Obj returns the inner NodeSelector.
func (s *NodeSelectorWrapper) Obj() *v1.NodeSelector {
return &s.NodeSelector
}
// LabelSelectorWrapper wraps a LabelSelector inside.
type LabelSelectorWrapper struct{ metav1.LabelSelector }
// MakeLabelSelector creates a LabelSelector wrapper.
func MakeLabelSelector() *LabelSelectorWrapper {
return &LabelSelectorWrapper{metav1.LabelSelector{}}
}
// Label applies a {k,v} pair to the inner LabelSelector.
func (s *LabelSelectorWrapper) Label(k, v string) *LabelSelectorWrapper {
if s.MatchLabels == nil {
s.MatchLabels = make(map[string]string)
}
s.MatchLabels[k] = v
return s
}
// In injects a matchExpression (with an operator In) to the inner labelSelector.
func (s *LabelSelectorWrapper) In(key string, vals []string) *LabelSelectorWrapper {
expression := metav1.LabelSelectorRequirement{
Key: key,
Operator: metav1.LabelSelectorOpIn,
Values: vals,
}
s.MatchExpressions = append(s.MatchExpressions, expression)
return s
}
// NotIn injects a matchExpression (with an operator NotIn) to the inner labelSelector.
func (s *LabelSelectorWrapper) NotIn(key string, vals []string) *LabelSelectorWrapper {
expression := metav1.LabelSelectorRequirement{
Key: key,
Operator: metav1.LabelSelectorOpNotIn,
Values: vals,
}
s.MatchExpressions = append(s.MatchExpressions, expression)
return s
}
// Exists injects a matchExpression (with an operator Exists) to the inner labelSelector.
func (s *LabelSelectorWrapper) Exists(k string) *LabelSelectorWrapper {
expression := metav1.LabelSelectorRequirement{
Key: k,
Operator: metav1.LabelSelectorOpExists,
}
s.MatchExpressions = append(s.MatchExpressions, expression)
return s
}
// NotExist injects a matchExpression (with an operator NotExist) to the inner labelSelector.
func (s *LabelSelectorWrapper) NotExist(k string) *LabelSelectorWrapper {
expression := metav1.LabelSelectorRequirement{
Key: k,
Operator: metav1.LabelSelectorOpDoesNotExist,
}
s.MatchExpressions = append(s.MatchExpressions, expression)
return s
}
// Obj returns the inner LabelSelector.
func (s *LabelSelectorWrapper) Obj() *metav1.LabelSelector {
return &s.LabelSelector
}
// ContainerWrapper wraps a Container inside.
type ContainerWrapper struct{ v1.Container }
// MakeContainer creates a Container wrapper.
func MakeContainer() *ContainerWrapper {
return &ContainerWrapper{v1.Container{}}
}
// Obj returns the inner Container.
func (c *ContainerWrapper) Obj() v1.Container {
return c.Container
}
// Name sets `n` as the name of the inner Container.
func (c *ContainerWrapper) Name(n string) *ContainerWrapper {
c.Container.Name = n
return c
}
// Image sets `image` as the image of the inner Container.
func (c *ContainerWrapper) Image(image string) *ContainerWrapper {
c.Container.Image = image
return c
}
// HostPort sets `hostPort` as the host port of the inner Container.
func (c *ContainerWrapper) HostPort(hostPort int32) *ContainerWrapper {
c.Container.Ports = []v1.ContainerPort{{HostPort: hostPort}}
return c
}
// ContainerPort sets `ports` as the ports of the inner Container.
func (c *ContainerWrapper) ContainerPort(ports []v1.ContainerPort) *ContainerWrapper {
c.Container.Ports = ports
return c
}
// Resources sets the container resources to the given resource map.
func (c *ContainerWrapper) Resources(resMap map[v1.ResourceName]string) *ContainerWrapper {
res := v1.ResourceList{}
for k, v := range resMap {
res[k] = resource.MustParse(v)
}
c.Container.Resources = v1.ResourceRequirements{
Requests: res,
Limits: res,
}
return c
}
// PodWrapper wraps a Pod inside.
type PodWrapper struct{ v1.Pod }
// MakePod creates a Pod wrapper.
func MakePod() *PodWrapper {
return &PodWrapper{v1.Pod{}}
}
// Obj returns the inner Pod.
func (p *PodWrapper) Obj() *v1.Pod {
return &p.Pod
}
// Name sets `s` as the name of the inner pod.
func (p *PodWrapper) Name(s string) *PodWrapper {
p.SetName(s)
return p
}
// UID sets `s` as the UID of the inner pod.
func (p *PodWrapper) UID(s string) *PodWrapper {
p.SetUID(types.UID(s))
return p
}
// SchedulerName sets `s` as the scheduler name of the inner pod.
func (p *PodWrapper) SchedulerName(s string) *PodWrapper {
p.Spec.SchedulerName = s
return p
}
// Namespace sets `s` as the namespace of the inner pod.
func (p *PodWrapper) Namespace(s string) *PodWrapper {
p.SetNamespace(s)
return p
}
// OwnerReference updates the owning controller of the pod.
func (p *PodWrapper) OwnerReference(name string, gvk schema.GroupVersionKind) *PodWrapper {
p.OwnerReferences = []metav1.OwnerReference{
{
APIVersion: gvk.GroupVersion().String(),
Kind: gvk.Kind,
Name: name,
Controller: pointer.Bool(true),
},
}
return p
}
// Container appends a container into PodSpec of the inner pod.
func (p *PodWrapper) Container(s string) *PodWrapper {
name := fmt.Sprintf("con%d", len(p.Spec.Containers))
p.Spec.Containers = append(p.Spec.Containers, MakeContainer().Name(name).Image(s).Obj())
return p
}
// Containers sets `containers` to the PodSpec of the inner pod.
func (p *PodWrapper) Containers(containers []v1.Container) *PodWrapper {
p.Spec.Containers = containers
return p
}
// Priority sets a priority value into PodSpec of the inner pod.
func (p *PodWrapper) Priority(val int32) *PodWrapper {
p.Spec.Priority = &val
return p
}
// CreationTimestamp sets the inner pod's CreationTimestamp.
func (p *PodWrapper) CreationTimestamp(t metav1.Time) *PodWrapper {
p.ObjectMeta.CreationTimestamp = t
return p
}
// Terminating sets the inner pod's deletionTimestamp to current timestamp.
func (p *PodWrapper) Terminating() *PodWrapper {
now := metav1.Now()
p.DeletionTimestamp = &now
return p
}
// ZeroTerminationGracePeriod sets the TerminationGracePeriodSeconds of the inner pod to zero.
func (p *PodWrapper) ZeroTerminationGracePeriod() *PodWrapper {
p.Spec.TerminationGracePeriodSeconds = &zero
return p
}
// Node sets `s` as the nodeName of the inner pod.
func (p *PodWrapper) Node(s string) *PodWrapper {
p.Spec.NodeName = s
return p
}
// NodeSelector sets `m` as the nodeSelector of the inner pod.
func (p *PodWrapper) NodeSelector(m map[string]string) *PodWrapper {
p.Spec.NodeSelector = m
return p
}
// NodeAffinityIn creates a HARD node affinity (with the operator In)
// and injects into the inner pod.
func (p *PodWrapper) NodeAffinityIn(key string, vals []string) *PodWrapper {
if p.Spec.Affinity == nil {
p.Spec.Affinity = &v1.Affinity{}
}
if p.Spec.Affinity.NodeAffinity == nil {
p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{}
}
nodeSelector := MakeNodeSelector().In(key, vals).Obj()
p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector
return p
}
// NodeAffinityNotIn creates a HARD node affinity (with the operator NotIn)
// and injects into the inner pod.
func (p *PodWrapper) NodeAffinityNotIn(key string, vals []string) *PodWrapper {
if p.Spec.Affinity == nil {
p.Spec.Affinity = &v1.Affinity{}
}
if p.Spec.Affinity.NodeAffinity == nil {
p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{}
}
nodeSelector := MakeNodeSelector().NotIn(key, vals).Obj()
p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector
return p
}
// StartTime sets `t` as .status.startTime for the inner pod.
func (p *PodWrapper) StartTime(t metav1.Time) *PodWrapper {
p.Status.StartTime = &t
return p
}
// NominatedNodeName sets `n` as the .Status.NominatedNodeName of the inner pod.
func (p *PodWrapper) NominatedNodeName(n string) *PodWrapper {
p.Status.NominatedNodeName = n
return p
}
// Phase sets `phase` as .status.Phase of the inner pod.
func (p *PodWrapper) Phase(phase v1.PodPhase) *PodWrapper {
p.Status.Phase = phase
return p
}
// Condition adds a `condition(Type, Status, Reason)` to .Status.Conditions.
func (p *PodWrapper) Condition(t v1.PodConditionType, s v1.ConditionStatus, r string) *PodWrapper {
p.Status.Conditions = append(p.Status.Conditions, v1.PodCondition{Type: t, Status: s, Reason: r})
return p
}
// Conditions sets `conditions` as .status.Conditions of the inner pod.
func (p *PodWrapper) Conditions(conditions []v1.PodCondition) *PodWrapper {
p.Status.Conditions = append(p.Status.Conditions, conditions...)
return p
}
// Toleration creates a toleration (with the operator Exists)
// and injects into the inner pod.
func (p *PodWrapper) Toleration(key string) *PodWrapper {
p.Spec.Tolerations = append(p.Spec.Tolerations, v1.Toleration{
Key: key,
Operator: v1.TolerationOpExists,
})
return p
}
// HostPort creates a container with a hostPort valued `hostPort`,
// and injects into the inner pod.
func (p *PodWrapper) HostPort(port int32) *PodWrapper {
p.Spec.Containers = append(p.Spec.Containers, MakeContainer().Name("container").Image("pause").HostPort(port).Obj())
return p
}
// ContainerPort creates a container with ports valued `ports`,
// and injects into the inner pod.
func (p *PodWrapper) ContainerPort(ports []v1.ContainerPort) *PodWrapper {
p.Spec.Containers = append(p.Spec.Containers, MakeContainer().Name("container").Image("pause").ContainerPort(ports).Obj())
return p
}
// PVC creates a Volume with a PVC and injects into the inner pod.
func (p *PodWrapper) PVC(name string) *PodWrapper {
p.Spec.Volumes = append(p.Spec.Volumes, v1.Volume{
Name: name,
VolumeSource: v1.VolumeSource{
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ClaimName: name},
},
})
return p
}
// Volume creates volume and injects into the inner pod.
func (p *PodWrapper) Volume(volume v1.Volume) *PodWrapper {
p.Spec.Volumes = append(p.Spec.Volumes, volume)
return p
}
// PodAffinityKind represents different kinds of PodAffinity.
type PodAffinityKind int
const (
// NilPodAffinity is a no-op which doesn't apply any PodAffinity.
NilPodAffinity PodAffinityKind = iota
// PodAffinityWithRequiredReq applies a HARD requirement to pod.spec.affinity.PodAffinity.
PodAffinityWithRequiredReq
// PodAffinityWithPreferredReq applies a SOFT requirement to pod.spec.affinity.PodAffinity.
PodAffinityWithPreferredReq
// PodAffinityWithRequiredPreferredReq applies HARD and SOFT requirements to pod.spec.affinity.PodAffinity.
PodAffinityWithRequiredPreferredReq
// PodAntiAffinityWithRequiredReq applies a HARD requirement to pod.spec.affinity.PodAntiAffinity.
PodAntiAffinityWithRequiredReq
// PodAntiAffinityWithPreferredReq applies a SOFT requirement to pod.spec.affinity.PodAntiAffinity.
PodAntiAffinityWithPreferredReq
// PodAntiAffinityWithRequiredPreferredReq applies HARD and SOFT requirements to pod.spec.affinity.PodAntiAffinity.
PodAntiAffinityWithRequiredPreferredReq
)
// PodAffinity creates a PodAffinity with topology key and label selector
// and injects into the inner pod.
func (p *PodWrapper) PodAffinity(topologyKey string, labelSelector *metav1.LabelSelector, kind PodAffinityKind) *PodWrapper {
if kind == NilPodAffinity {
return p
}
if p.Spec.Affinity == nil {
p.Spec.Affinity = &v1.Affinity{}
}
if p.Spec.Affinity.PodAffinity == nil {
p.Spec.Affinity.PodAffinity = &v1.PodAffinity{}
}
term := v1.PodAffinityTerm{LabelSelector: labelSelector, TopologyKey: topologyKey}
switch kind {
case PodAffinityWithRequiredReq:
p.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution,
term,
)
case PodAffinityWithPreferredReq:
p.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution,
v1.WeightedPodAffinityTerm{Weight: 1, PodAffinityTerm: term},
)
case PodAffinityWithRequiredPreferredReq:
p.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution,
term,
)
p.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution,
v1.WeightedPodAffinityTerm{Weight: 1, PodAffinityTerm: term},
)
}
return p
}
// PodAntiAffinity creates a PodAntiAffinity with topology key and label selector
// and injects into the inner pod.
func (p *PodWrapper) PodAntiAffinity(topologyKey string, labelSelector *metav1.LabelSelector, kind PodAffinityKind) *PodWrapper {
if kind == NilPodAffinity {
return p
}
if p.Spec.Affinity == nil {
p.Spec.Affinity = &v1.Affinity{}
}
if p.Spec.Affinity.PodAntiAffinity == nil {
p.Spec.Affinity.PodAntiAffinity = &v1.PodAntiAffinity{}
}
term := v1.PodAffinityTerm{LabelSelector: labelSelector, TopologyKey: topologyKey}
switch kind {
case PodAntiAffinityWithRequiredReq:
p.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution,
term,
)
case PodAntiAffinityWithPreferredReq:
p.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution,
v1.WeightedPodAffinityTerm{Weight: 1, PodAffinityTerm: term},
)
case PodAntiAffinityWithRequiredPreferredReq:
p.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution,
term,
)
p.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(
p.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution,
v1.WeightedPodAffinityTerm{Weight: 1, PodAffinityTerm: term},
)
}
return p
}
// PodAffinityExists creates a PodAffinity with the operator "Exists"
// and injects into the inner pod.
func (p *PodWrapper) PodAffinityExists(labelKey, topologyKey string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().Exists(labelKey).Obj()
p.PodAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAntiAffinityExists creates a PodAntiAffinity with the operator "Exists"
// and injects into the inner pod.
func (p *PodWrapper) PodAntiAffinityExists(labelKey, topologyKey string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().Exists(labelKey).Obj()
p.PodAntiAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAffinityNotExists creates a PodAffinity with the operator "NotExists"
// and injects into the inner pod.
func (p *PodWrapper) PodAffinityNotExists(labelKey, topologyKey string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().NotExist(labelKey).Obj()
p.PodAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAntiAffinityNotExists creates a PodAntiAffinity with the operator "NotExists"
// and injects into the inner pod.
func (p *PodWrapper) PodAntiAffinityNotExists(labelKey, topologyKey string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().NotExist(labelKey).Obj()
p.PodAntiAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAffinityIn creates a PodAffinity with the operator "In"
// and injects into the inner pod.
func (p *PodWrapper) PodAffinityIn(labelKey, topologyKey string, vals []string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().In(labelKey, vals).Obj()
p.PodAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAntiAffinityIn creates a PodAntiAffinity with the operator "In"
// and injects into the inner pod.
func (p *PodWrapper) PodAntiAffinityIn(labelKey, topologyKey string, vals []string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().In(labelKey, vals).Obj()
p.PodAntiAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAffinityNotIn creates a PodAffinity with the operator "NotIn"
// and injects into the inner pod.
func (p *PodWrapper) PodAffinityNotIn(labelKey, topologyKey string, vals []string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().NotIn(labelKey, vals).Obj()
p.PodAffinity(topologyKey, labelSelector, kind)
return p
}
// PodAntiAffinityNotIn creates a PodAntiAffinity with the operator "NotIn"
// and injects into the inner pod.
func (p *PodWrapper) PodAntiAffinityNotIn(labelKey, topologyKey string, vals []string, kind PodAffinityKind) *PodWrapper {
labelSelector := MakeLabelSelector().NotIn(labelKey, vals).Obj()
p.PodAntiAffinity(topologyKey, labelSelector, kind)
return p
}
// SpreadConstraint constructs a TopologySpreadConstraint object and injects
// into the inner pod.
func (p *PodWrapper) SpreadConstraint(maxSkew int, tpKey string, mode v1.UnsatisfiableConstraintAction, selector *metav1.LabelSelector, minDomains *int32, nodeAffinityPolicy, nodeTaintsPolicy *v1.NodeInclusionPolicy, matchLabelKeys []string) *PodWrapper {
c := v1.TopologySpreadConstraint{
MaxSkew: int32(maxSkew),
TopologyKey: tpKey,
WhenUnsatisfiable: mode,
LabelSelector: selector,
MinDomains: minDomains,
NodeAffinityPolicy: nodeAffinityPolicy,
NodeTaintsPolicy: nodeTaintsPolicy,
MatchLabelKeys: matchLabelKeys,
}
p.Spec.TopologySpreadConstraints = append(p.Spec.TopologySpreadConstraints, c)
return p
}
// Label sets a {k,v} pair to the inner pod label.
func (p *PodWrapper) Label(k, v string) *PodWrapper {
if p.ObjectMeta.Labels == nil {
p.ObjectMeta.Labels = make(map[string]string)
}
p.ObjectMeta.Labels[k] = v
return p
}
// Labels sets all {k,v} pair provided by `labels` to the inner pod labels.
func (p *PodWrapper) Labels(labels map[string]string) *PodWrapper {
for k, v := range labels {
p.Label(k, v)
}
return p
}
// Annotation sets a {k,v} pair to the inner pod annotation.
func (p *PodWrapper) Annotation(key, value string) *PodWrapper {
if p.ObjectMeta.Annotations == nil {
p.ObjectMeta.Annotations = make(map[string]string)
}
p.ObjectMeta.Annotations[key] = value
return p
}
// Annotations sets all {k,v} pair provided by `annotations` to the inner pod annotations.
func (p *PodWrapper) Annotations(annotations map[string]string) *PodWrapper {
for k, v := range annotations {
p.Annotation(k, v)
}
return p
}
// Req adds a new container to the inner pod with given resource map.
func (p *PodWrapper) Req(resMap map[v1.ResourceName]string) *PodWrapper {
if len(resMap) == 0 {
return p
}
name := fmt.Sprintf("con%d", len(p.Spec.Containers))
p.Spec.Containers = append(p.Spec.Containers, MakeContainer().Name(name).Image(imageutils.GetPauseImageName()).Resources(resMap).Obj())
return p
}
// InitReq adds a new init container to the inner pod with given resource map.
func (p *PodWrapper) InitReq(resMap map[v1.ResourceName]string) *PodWrapper {
if len(resMap) == 0 {
return p
}
name := fmt.Sprintf("init-con%d", len(p.Spec.InitContainers))
p.Spec.InitContainers = append(p.Spec.InitContainers, MakeContainer().Name(name).Image(imageutils.GetPauseImageName()).Resources(resMap).Obj())
return p
}
// PreemptionPolicy sets the give preemption policy to the inner pod.
func (p *PodWrapper) PreemptionPolicy(policy v1.PreemptionPolicy) *PodWrapper {
p.Spec.PreemptionPolicy = &policy
return p
}
// Overhead sets the give ResourceList to the inner pod
func (p *PodWrapper) Overhead(rl v1.ResourceList) *PodWrapper {
p.Spec.Overhead = rl
return p
}
// NodeWrapper wraps a Node inside.
type NodeWrapper struct{ v1.Node }
// MakeNode creates a Node wrapper.
func MakeNode() *NodeWrapper {
w := &NodeWrapper{v1.Node{}}
return w.Capacity(nil)
}
// Obj returns the inner Node.
func (n *NodeWrapper) Obj() *v1.Node {
return &n.Node
}
// Name sets `s` as the name of the inner pod.
func (n *NodeWrapper) Name(s string) *NodeWrapper {
n.SetName(s)
return n
}
// UID sets `s` as the UID of the inner pod.
func (n *NodeWrapper) UID(s string) *NodeWrapper {
n.SetUID(types.UID(s))
return n
}
// Label applies a {k,v} label pair to the inner node.
func (n *NodeWrapper) Label(k, v string) *NodeWrapper {
if n.Labels == nil {
n.Labels = make(map[string]string)
}
n.Labels[k] = v
return n
}
// Capacity sets the capacity and the allocatable resources of the inner node.
// Each entry in `resources` corresponds to a resource name and its quantity.
// By default, the capacity and allocatable number of pods are set to 32.
func (n *NodeWrapper) Capacity(resources map[v1.ResourceName]string) *NodeWrapper {
res := v1.ResourceList{
v1.ResourcePods: resource.MustParse("32"),
}
for name, value := range resources {
res[name] = resource.MustParse(value)
}
n.Status.Capacity, n.Status.Allocatable = res, res
return n
}
// Images sets the images of the inner node. Each entry in `images` corresponds
// to an image name and its size in bytes.
func (n *NodeWrapper) Images(images map[string]int64) *NodeWrapper {
var containerImages []v1.ContainerImage
for name, size := range images {
containerImages = append(containerImages, v1.ContainerImage{Names: []string{name}, SizeBytes: size})
}
n.Status.Images = containerImages
return n
}
// Taints applies taints to the inner node.
func (n *NodeWrapper) Taints(taints []v1.Taint) *NodeWrapper {
n.Spec.Taints = taints
return n
}