1
16
17 package volumebinding
18
19 import (
20 "fmt"
21
22 v1 "k8s.io/api/core/v1"
23 "k8s.io/apimachinery/pkg/api/resource"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/component-helpers/storage/volume"
26 "k8s.io/utils/ptr"
27 )
28
29 type nodeBuilder struct {
30 *v1.Node
31 }
32
33 func makeNode(name string) nodeBuilder {
34 return nodeBuilder{Node: &v1.Node{
35 ObjectMeta: metav1.ObjectMeta{
36 Name: name,
37 Labels: map[string]string{
38 v1.LabelHostname: name,
39 },
40 },
41 }}
42 }
43
44 func (nb nodeBuilder) withLabel(key, value string) nodeBuilder {
45 if nb.Node.ObjectMeta.Labels == nil {
46 nb.Node.ObjectMeta.Labels = map[string]string{}
47 }
48 nb.Node.ObjectMeta.Labels[key] = value
49 return nb
50 }
51
52 type pvBuilder struct {
53 *v1.PersistentVolume
54 }
55
56 func makePV(name, className string) pvBuilder {
57 return pvBuilder{PersistentVolume: &v1.PersistentVolume{
58 ObjectMeta: metav1.ObjectMeta{
59 Name: name,
60 },
61 Spec: v1.PersistentVolumeSpec{
62 StorageClassName: className,
63 },
64 }}
65 }
66
67 func (pvb pvBuilder) withNodeAffinity(keyValues map[string][]string) pvBuilder {
68 matchExpressions := make([]v1.NodeSelectorRequirement, 0)
69 for key, values := range keyValues {
70 matchExpressions = append(matchExpressions, v1.NodeSelectorRequirement{
71 Key: key,
72 Operator: v1.NodeSelectorOpIn,
73 Values: values,
74 })
75 }
76 pvb.PersistentVolume.Spec.NodeAffinity = &v1.VolumeNodeAffinity{
77 Required: &v1.NodeSelector{
78 NodeSelectorTerms: []v1.NodeSelectorTerm{
79 {
80 MatchExpressions: matchExpressions,
81 },
82 },
83 },
84 }
85 return pvb
86 }
87
88 func (pvb pvBuilder) withVersion(version string) pvBuilder {
89 pvb.PersistentVolume.ObjectMeta.ResourceVersion = version
90 return pvb
91 }
92
93 func (pvb pvBuilder) withCapacity(capacity resource.Quantity) pvBuilder {
94 pvb.PersistentVolume.Spec.Capacity = v1.ResourceList{
95 v1.ResourceName(v1.ResourceStorage): capacity,
96 }
97 return pvb
98 }
99
100 func (pvb pvBuilder) withPhase(phase v1.PersistentVolumePhase) pvBuilder {
101 pvb.PersistentVolume.Status = v1.PersistentVolumeStatus{
102 Phase: phase,
103 }
104 return pvb
105 }
106
107 type pvcBuilder struct {
108 *v1.PersistentVolumeClaim
109 }
110
111 func makePVC(name string, storageClassName string) pvcBuilder {
112 return pvcBuilder{PersistentVolumeClaim: &v1.PersistentVolumeClaim{
113 ObjectMeta: metav1.ObjectMeta{
114 Name: name,
115 Namespace: v1.NamespaceDefault,
116 },
117 Spec: v1.PersistentVolumeClaimSpec{
118 StorageClassName: ptr.To(storageClassName),
119 },
120 }}
121 }
122
123 func (pvcb pvcBuilder) withBoundPV(pvName string) pvcBuilder {
124 pvcb.PersistentVolumeClaim.Spec.VolumeName = pvName
125 metav1.SetMetaDataAnnotation(&pvcb.PersistentVolumeClaim.ObjectMeta, volume.AnnBindCompleted, "true")
126 return pvcb
127 }
128
129 func (pvcb pvcBuilder) withRequestStorage(request resource.Quantity) pvcBuilder {
130 pvcb.PersistentVolumeClaim.Spec.Resources = v1.VolumeResourceRequirements{
131 Requests: v1.ResourceList{
132 v1.ResourceName(v1.ResourceStorage): request,
133 },
134 }
135 return pvcb
136 }
137
138 func (pvcb pvcBuilder) withPhase(phase v1.PersistentVolumeClaimPhase) pvcBuilder {
139 pvcb.PersistentVolumeClaim.Status = v1.PersistentVolumeClaimStatus{
140 Phase: phase,
141 }
142 return pvcb
143 }
144
145 type podBuilder struct {
146 *v1.Pod
147 }
148
149 func makePod(name string) podBuilder {
150 pb := podBuilder{Pod: &v1.Pod{
151 ObjectMeta: metav1.ObjectMeta{
152 Name: name,
153 Namespace: v1.NamespaceDefault,
154 },
155 }}
156 pb.Pod.Spec.Volumes = make([]v1.Volume, 0)
157 return pb
158 }
159
160 func (pb podBuilder) withNodeName(name string) podBuilder {
161 pb.Pod.Spec.NodeName = name
162 return pb
163 }
164
165 func (pb podBuilder) withNamespace(name string) podBuilder {
166 pb.Pod.ObjectMeta.Namespace = name
167 return pb
168 }
169
170 func (pb podBuilder) withPVCVolume(pvcName, name string) podBuilder {
171 pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{
172 Name: name,
173 VolumeSource: v1.VolumeSource{
174 PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
175 ClaimName: pvcName,
176 },
177 },
178 })
179 return pb
180 }
181
182 func (pb podBuilder) withPVCSVolume(pvcs []*v1.PersistentVolumeClaim) podBuilder {
183 for i, pvc := range pvcs {
184 pb.withPVCVolume(pvc.Name, fmt.Sprintf("vol%v", i))
185 }
186 return pb
187 }
188
189 func (pb podBuilder) withEmptyDirVolume() podBuilder {
190 pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{
191 VolumeSource: v1.VolumeSource{
192 EmptyDir: &v1.EmptyDirVolumeSource{},
193 },
194 })
195 return pb
196 }
197
198 func (pb podBuilder) withGenericEphemeralVolume(name string) podBuilder {
199 pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{
200 Name: name,
201 VolumeSource: v1.VolumeSource{
202 Ephemeral: &v1.EphemeralVolumeSource{},
203 },
204 })
205 return pb
206 }
207
View as plain text