/
pvcs.go
131 lines (114 loc) · 3.65 KB
/
pvcs.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
/*
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 util
import (
"fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
)
// PVCsStartupStatus represents phase of a pvc group.
type PVCsStartupStatus struct {
Pending int
Bound int
Lost int
Expected int
Created int
}
// String returns string representation for PVCsStartupStatus.
func (s *PVCsStartupStatus) String() string {
return fmt.Sprintf("PVCs: %d out of %d created, %d bound, %d pending, %d lost", s.Created, s.Expected, s.Bound, s.Pending, s.Lost)
}
// ComputePVCsStartupStatus computes PVCsStartupStatus for a group of PVCs.
func ComputePVCsStartupStatus(pvcs []*corev1.PersistentVolumeClaim, expected int) PVCsStartupStatus {
startupStatus := PVCsStartupStatus{
Expected: expected,
}
for _, p := range pvcs {
startupStatus.Created++
if p.Status.Phase == corev1.ClaimPending {
startupStatus.Pending++
} else if p.Status.Phase == corev1.ClaimBound {
startupStatus.Bound++
} else if p.Status.Phase == corev1.ClaimLost {
startupStatus.Lost++
}
}
return startupStatus
}
type pvcInfo struct {
oldPhase string
phase string
}
// PVCDiff represets diff between old and new group of pvcs.
type PVCDiff map[string]*pvcInfo
// Print formats and prints the give PVCDiff.
func (p PVCDiff) String(ignorePhases sets.String) string {
ret := ""
for name, info := range p {
if ignorePhases.Has(info.phase) {
continue
}
if info.phase == nonExist {
ret += fmt.Sprintf("PVC %v was deleted, had phase %v\n", name, info.oldPhase)
continue
}
msg := fmt.Sprintf("PVC %v ", name)
if info.oldPhase != info.phase {
if info.oldPhase == nonExist {
msg += fmt.Sprintf("in phase %v ", info.phase)
} else {
msg += fmt.Sprintf("went from phase: %v -> %v ", info.oldPhase, info.phase)
}
ret += msg + "\n"
}
}
return ret
}
// DeletedPVCs returns a slice of PVCs that were present at the beginning
// and then disappeared.
func (p PVCDiff) DeletedPVCs() []string {
var deletedPVCs []string
for pvcName, pvcInfo := range p {
if pvcInfo.phase == nonExist {
deletedPVCs = append(deletedPVCs, pvcName)
}
}
return deletedPVCs
}
// AddedPVCs returns a slice of PVCs that were added.
func (p PVCDiff) AddedPVCs() []string {
var addedPVCs []string
for pvcName, pvcInfo := range p {
if pvcInfo.oldPhase == nonExist {
addedPVCs = append(addedPVCs, pvcName)
}
}
return addedPVCs
}
// DiffPVCs computes a PVCDiff given 2 lists of PVCs.
func DiffPVCs(oldPVCs []*corev1.PersistentVolumeClaim, curPVCs []*corev1.PersistentVolumeClaim) PVCDiff {
pvcInfoMap := PVCDiff{}
// New PVCs will show up in the curPVCs list but not in oldPVCs. They have oldhostname/phase == nonexist.
for _, pvc := range curPVCs {
pvcInfoMap[pvc.Name] = &pvcInfo{phase: string(pvc.Status.Phase), oldPhase: nonExist}
}
// Deleted PVCs will show up in the oldPVCs list but not in curPVCs. They have a hostname/phase == nonexist.
for _, pvc := range oldPVCs {
if info, ok := pvcInfoMap[pvc.Name]; ok {
info.oldPhase = string(pvc.Status.Phase)
} else {
pvcInfoMap[pvc.Name] = &pvcInfo{phase: nonExist, oldPhase: string(pvc.Status.Phase)}
}
}
return pvcInfoMap
}