/
blockdeviceclaim.go
254 lines (216 loc) · 7.53 KB
/
blockdeviceclaim.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
Copyright 2019 The OpenEBS 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 v1alpha1
import (
apis "github.com/openebs/maya/pkg/apis/openebs.io/ndm/v1alpha1"
ndm "github.com/openebs/maya/pkg/apis/openebs.io/ndm/v1alpha1"
"github.com/openebs/maya/pkg/util"
"github.com/pkg/errors"
"k8s.io/klog"
)
// BlockDeviceClaim encapsulates BlockDeviceClaim api object.
type BlockDeviceClaim struct {
// actual block device claim object
Object *ndm.BlockDeviceClaim
// kubeconfig path
configPath string
}
// BlockDeviceClaimList encapsulates BlockDeviceClaimList api object
type BlockDeviceClaimList struct {
// list of blockdeviceclaims
ObjectList *ndm.BlockDeviceClaimList
}
// Predicate defines an abstraction to determine conditional checks against the
// provided block device claim instance
type Predicate func(*BlockDeviceClaim) bool
// PredicateList holds the list of Predicates
type PredicateList []Predicate
// all returns true if all the predicates succeed against the provided block
// device instance.
func (l PredicateList) all(c *BlockDeviceClaim) bool {
for _, pred := range l {
if !pred(c) {
return false
}
}
return true
}
// HasAnnotation is predicate to filter out based on
// annotation in BDC instances
func HasAnnotation(key, value string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.HasAnnotation(key, value)
}
}
// HasAnnotation return true if provided annotation
// key and value are present in the the provided BDCList
// instance
func (bdc *BlockDeviceClaim) HasAnnotation(key, value string) bool {
val, ok := bdc.Object.GetAnnotations()[key]
if ok {
return val == value
}
return false
}
// HasAnnotationKey is predicate to filter out based on
// annotation key in BDC instances
func HasAnnotationKey(key string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.HasAnnotationKey(key)
}
}
// HasAnnotationKey return true if provided annotation
// key is present in the the provided BDC instance.
func (bdc *BlockDeviceClaim) HasAnnotationKey(key string) bool {
_, ok := bdc.Object.GetAnnotations()[key]
return ok
}
// HasBD is predicate to filter out based on BD.
func HasBD(bdName string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.HasBD(bdName)
}
}
// HasBD return true if provided BD belongs to the BDC instance.
func (bdc *BlockDeviceClaim) HasBD(bdName string) bool {
return bdc.Object.Spec.BlockDeviceName == bdName
}
// HasLabel is predicate to filter out labeled
// BDC instances.
func HasLabel(key, value string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.HasLabel(key, value)
}
}
// HasLabel returns true if provided label
// key and value are present in the provided BDC(BlockDeviceClaim)
// instance
func (bdc *BlockDeviceClaim) HasLabel(key, value string) bool {
val, ok := bdc.Object.GetLabels()[key]
if ok {
return val == value
}
return false
}
// HasFinalizer is a predicate to filter out based on provided
// finalizer being present on the object.
func HasFinalizer(finalizer string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.HasFinalizer(finalizer)
}
}
// HasFinalizer returns true if the provided finalizer is present on the object.
func (bdc *BlockDeviceClaim) HasFinalizer(finalizer string) bool {
finalizersList := bdc.Object.GetFinalizers()
return util.ContainsString(finalizersList, finalizer)
}
// AddFinalizer adds the given finalizer to the object.
func (bdc *BlockDeviceClaim) AddFinalizer(finalizer string) (*ndm.BlockDeviceClaim, error) {
if bdc.HasFinalizer(finalizer) {
klog.V(2).Infof("finalizer %s is already present on BDC %s", finalizer, bdc.Object.Name)
return bdc.Object, nil
}
bdc.Object.Finalizers = append(bdc.Object.Finalizers, finalizer)
bdcAPIObj, err := NewKubeClient(WithKubeConfigPath(bdc.configPath)).
WithNamespace(bdc.Object.Namespace).
Update(bdc.Object)
if err != nil {
return nil, errors.Wrapf(err, "failed to update bdc %s while adding finalizer %s",
bdc.Object.Name, finalizer)
}
klog.Infof("Finalizer %s added on blockdeviceclaim %s", finalizer, bdc.Object.Name)
return bdcAPIObj, nil
}
// RemoveFinalizer removes the given finalizer from the object.
func (bdc *BlockDeviceClaim) RemoveFinalizer(
finalizer string) (*ndm.BlockDeviceClaim, error) {
if len(bdc.Object.Finalizers) == 0 {
klog.V(2).Infof("no finalizer present on BDC %s", bdc.Object.Name)
return bdc.Object, nil
}
if !bdc.HasFinalizer(finalizer) {
klog.V(2).Infof("finalizer %s is already removed on BDC %s", finalizer, bdc.Object.Name)
return bdc.Object, nil
}
bdc.Object.Finalizers = util.RemoveString(bdc.Object.Finalizers, finalizer)
newBDC, err := NewKubeClient(WithKubeConfigPath(bdc.configPath)).
WithNamespace(bdc.Object.Namespace).
Update(bdc.Object)
if err != nil {
return nil, errors.Wrap(err, "failed to update object while removing finalizer")
}
klog.Infof("Finalizer %s removed successfully from BDC %s", finalizer, bdc.Object.Name)
return newBDC, nil
}
// IsStatus is predicate to filter out BDC instances based on argument provided
func IsStatus(status string) Predicate {
return func(bdc *BlockDeviceClaim) bool {
return bdc.IsStatus(status)
}
}
// IsStatus returns true if the status on
// block device claim matches with provided status.
func (bdc *BlockDeviceClaim) IsStatus(status string) bool {
return string(bdc.Object.Status.Phase) == status
}
// GetSpecHostName return hostName from spec of blockdeviceclaim
func (bdc *BlockDeviceClaim) GetSpecHostName() string {
return bdc.Object.Spec.HostName
}
// GetNodeAtributesHostName return hostName from blockdeviceclaim attribute hostName
func (bdc *BlockDeviceClaim) GetNodeAtributesHostName() string {
return bdc.Object.Spec.BlockDeviceNodeAttributes.HostName
}
// GetHostName return hostName from blockdeviceclaim
func (bdc *BlockDeviceClaim) GetHostName() string {
hostName := bdc.GetNodeAtributesHostName()
if hostName == "" {
return bdc.GetSpecHostName()
}
return hostName
}
// Len returns the length og BlockDeviceClaimList.
func (bdcl *BlockDeviceClaimList) Len() int {
return len(bdcl.ObjectList.Items)
}
// GetBlockDeviceNamesByNode returns map of node name and corresponding blockdevices to that
// node from blockdeviceclaim list
func (bdcl *BlockDeviceClaimList) GetBlockDeviceNamesByNode() map[string][]string {
newNodeBDList := make(map[string][]string)
if bdcl == nil {
return newNodeBDList
}
for _, bdc := range bdcl.ObjectList.Items {
bdc := bdc
bdcObj := BlockDeviceClaim{Object: &bdc}
hostName := bdcObj.GetHostName()
newNodeBDList[hostName] = append(
newNodeBDList[hostName],
bdcObj.Object.Spec.BlockDeviceName,
)
}
return newNodeBDList
}
// GetBlockDeviceClaimFromBDName return block device claim if claim exists for
// provided blockdevice name in claim list else return error
func (bdcl *BlockDeviceClaimList) GetBlockDeviceClaimFromBDName(
bdName string) (*apis.BlockDeviceClaim, error) {
for _, bdc := range bdcl.ObjectList.Items {
// pin it
bdc := bdc
if bdc.Spec.BlockDeviceName == bdName {
return &bdc, nil
}
}
return nil, errors.Errorf("claim doesn't exist for blockdevice %s", bdName)
}