/
helpers.go
127 lines (114 loc) · 3.23 KB
/
helpers.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
package cluster
import (
"github.com/jenkins-x/jx/v2/pkg/kube/naming"
"github.com/jenkins-x/jx/v2/pkg/log"
"github.com/jenkins-x/jx/v2/pkg/util"
"github.com/pkg/errors"
uuid "github.com/satori/go.uuid"
)
// NewLabelValue returns a cluster safe unique label we can use for locking
func NewLabelValue() (string, error) {
id, err := uuid.NewV4()
if err != nil {
return "", err
}
return naming.ToValidName(id.String()), nil
}
// LockCluster tries to use the given label and value to lock the cluster.
// Return nil if there are no clusters available
func LockCluster(client Client, lockLabels map[string]string, filterLabels map[string]string) (*Cluster, error) {
clusters, err := client.ListFilter(filterLabels)
if err != nil {
return nil, err
}
for _, c := range clusters {
if !HasAnyKey(c.Labels, lockLabels) {
// lets try to update label
allLabels := util.MergeMaps(map[string]string{}, c.Labels, lockLabels)
err = client.SetClusterLabels(c, allLabels)
if err != nil {
return nil, errors.Wrapf(err, "failed to label cluster %s with label %#v", c.Name, lockLabels)
}
// now lets requery to verify the label got applied
copy, err := client.Get(c.Name)
if err != nil {
return nil, err
}
if copy != nil && LabelsMatch(copy.Labels, lockLabels) {
return copy, nil
}
if copy == nil {
log.Logger().Infof("cluster %s no longer exists", c.Name)
} else {
log.Logger().Infof("could not label cluster %s with lock labels %#v it has labels %#v so could be labelled by another process",
c.Name, lockLabels, copy.Labels)
}
}
}
return nil, nil
}
// GetCluster gets a cluster by listing the clusters
func GetCluster(client Client, name string) (*Cluster, error) {
clusters, err := client.List()
if err != nil {
return nil, err
}
for _, c := range clusters {
if c.Name == name {
return c, nil
}
}
return nil, nil
}
// ListFilter lists the clusters with a filter
func ListFilter(client Client, labels map[string]string) ([]*Cluster, error) {
answer := []*Cluster{}
clusters, err := client.List()
if err != nil {
return answer, err
}
for _, c := range clusters {
if LabelsMatch(c.Labels, labels) {
answer = append(answer, c)
}
}
return answer, nil
}
// LabelsMatch returns true if the filter labels are contained in the label map
func LabelsMatch(labels map[string]string, filter map[string]string) bool {
for k, v := range filter {
if labels == nil || labels[k] != v {
return false
}
}
return true
}
// HasAnyKey returns true if the labels map has none of the keys in the filter
func HasAnyKey(labels map[string]string, filters map[string]string) bool {
if labels != nil && filters != nil {
for k := range filters {
if labels[k] != "" {
return true
}
}
}
return false
}
// RemoveLabels removes the set of labels from the cluster
func RemoveLabels(client Client, cluster *Cluster, removeLabels []string) (map[string]string, error) {
if cluster.Labels == nil {
return cluster.Labels, nil
}
updated := false
for _, label := range removeLabels {
if _, ok := cluster.Labels[label]; ok {
delete(cluster.Labels, label)
updated = true
}
}
var err error
if updated {
err = client.SetClusterLabels(cluster, cluster.Labels)
}
return cluster.Labels, err
}