-
Notifications
You must be signed in to change notification settings - Fork 126
/
cluster_check.go
131 lines (116 loc) · 3.34 KB
/
cluster_check.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
package controller
import (
"os"
"reflect"
"strings"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
)
type ObjectClusterName interface {
ObjClusterName() string
}
func ObjectInCluster(cluster string, obj interface{}) bool {
// Check if the object implements the interface, this is best case and
// what objects should strive to be
if o, ok := obj.(ObjectClusterName); ok {
clusterName := o.ObjClusterName()
debugLogsClusterExtraction(clusterName, obj)
return clusterName == cluster
}
// For types outside of rancher, attempt to check the anno, then use the namespace
// This is much better than using the reflect hole below
switch v := obj.(type) {
case *corev1.Secret:
if c, ok := v.Annotations["field.cattle.io/projectId"]; ok {
if parts := strings.SplitN(c, ":", 2); len(parts) == 2 {
return cluster == parts[0]
}
}
return v.Namespace == cluster
case *corev1.Namespace:
if c, ok := v.Annotations["field.cattle.io/projectId"]; ok {
if parts := strings.SplitN(c, ":", 2); len(parts) == 2 {
return cluster == parts[0]
}
}
return v.Namespace == cluster
case *corev1.Node:
if c, ok := v.Annotations["field.cattle.io/projectId"]; ok {
if parts := strings.SplitN(c, ":", 2); len(parts) == 2 {
return cluster == parts[0]
}
}
return v.Namespace == cluster
}
// Seeing this message means something needs to be done with the type, see comments above
if dm := os.Getenv("CATTLE_DEV_MODE"); dm != "" {
logrus.Errorf("ObjectClusterName not implemented by type %T", obj)
}
var clusterName string
if c := getValue(obj, "ClusterName"); c.IsValid() {
clusterName = c.String()
}
if clusterName == "" {
if c := getValue(obj, "Spec", "ClusterName"); c.IsValid() {
clusterName = c.String()
}
}
if clusterName == "" {
if c := getValue(obj, "ProjectName"); c.IsValid() {
if parts := strings.SplitN(c.String(), ":", 2); len(parts) == 2 {
clusterName = parts[0]
}
}
}
if clusterName == "" {
if c := getValue(obj, "Spec", "ProjectName"); c.IsValid() {
if parts := strings.SplitN(c.String(), ":", 2); len(parts) == 2 {
clusterName = parts[0]
}
}
}
if clusterName == "" {
if a := getValue(obj, "Annotations"); a.IsValid() {
if c := a.MapIndex(reflect.ValueOf("field.cattle.io/projectId")); c.IsValid() {
if parts := strings.SplitN(c.String(), ":", 2); len(parts) == 2 {
clusterName = parts[0]
}
}
}
}
if clusterName == "" {
if c := getValue(obj, "Namespace"); c.IsValid() {
clusterName = c.String()
}
}
debugLogsClusterExtraction(clusterName, obj)
return clusterName == cluster
}
func getValue(obj interface{}, name ...string) reflect.Value {
v := reflect.ValueOf(obj)
t := v.Type()
if t.Kind() == reflect.Ptr {
v = v.Elem()
}
field := v.FieldByName(name[0])
if !field.IsValid() || len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func getFieldValue(v reflect.Value, name ...string) reflect.Value {
field := v.FieldByName(name[0])
if len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func debugLogsClusterExtraction(clusterName string, obj interface{}) {
if clusterName != "" {
return
}
ns := getValue(obj, "Namespace")
name := getValue(obj, "Name")
kind := getValue(obj, "Kind")
logrus.Debugf("unable to extract cluster that the object [%s:%s] of kind [%s] belongs to", ns, name, kind)
}