forked from jtblin/kube2iam
-
Notifications
You must be signed in to change notification settings - Fork 0
/
namespace.go
95 lines (80 loc) · 2.67 KB
/
namespace.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
package kube2iam
import (
"encoding/json"
"fmt"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
)
// NamespaceHandler outputs change events from K8.
type NamespaceHandler struct {
namespaceKey string
}
func (h *NamespaceHandler) namespaceFields(ns *v1.Namespace) log.Fields {
return log.Fields{
"ns.name": ns.GetName(),
}
}
// OnAdd called with a namespace is added to k8s.
func (h *NamespaceHandler) OnAdd(obj interface{}) {
ns, ok := obj.(*v1.Namespace)
if !ok {
log.Errorf("Expected Namespace but OnAdd handler received %+v", obj)
return
}
logger := log.WithFields(h.namespaceFields(ns))
logger.Debug("Namespace OnAdd")
roles := GetNamespaceRoleAnnotation(ns, h.namespaceKey)
for _, role := range roles {
logger.WithField("ns.role", role).Info("Discovered role on namespace (OnAdd)")
}
}
// OnUpdate called with a namespace is updated inside k8s.
func (h *NamespaceHandler) OnUpdate(oldObj, newObj interface{}) {
nns, ok := newObj.(*v1.Namespace)
if !ok {
log.Errorf("Expected Namespace but OnUpdate handler received %+v %+v", oldObj, newObj)
return
}
logger := log.WithFields(h.namespaceFields(nns))
logger.Debug("Namespace OnUpdate")
roles := GetNamespaceRoleAnnotation(nns, h.namespaceKey)
for _, role := range roles {
logger.WithField("ns.role", role).Info("Discovered role on namespace (OnUpdate)")
}
}
// OnDelete called with a namespace is removed from k8s.
func (h *NamespaceHandler) OnDelete(obj interface{}) {
ns, ok := obj.(*v1.Namespace)
if !ok {
log.Errorf("Expected Namespace but OnDelete handler received %+v", obj)
return
}
log.WithFields(h.namespaceFields(ns)).Info("Deleting namespace (OnDelete)")
}
// GetNamespaceRoleAnnotation reads the "iam.amazonaws.com/allowed-roles" annotation off a namespace
// and splits them as a JSON list (["role1", "role2", "role3"])
func GetNamespaceRoleAnnotation(ns *v1.Namespace, namespaceKey string) []string {
rolesString := ns.GetAnnotations()[namespaceKey]
if rolesString != "" {
var decoded []string
if err := json.Unmarshal([]byte(rolesString), &decoded); err != nil {
log.Errorf("Unable to decode roles on namespace %s ( role annotation is '%s' ) with error: %s", ns.Name, rolesString, err)
}
return decoded
}
return nil
}
// NamespaceIndexFunc maps a namespace to it's name.
func NamespaceIndexFunc(obj interface{}) ([]string, error) {
namespace, ok := obj.(*v1.Namespace)
if !ok {
return nil, fmt.Errorf("expected namespace but received: %+v", obj)
}
return []string{namespace.GetName()}, nil
}
// NewNamespaceHandler returns a new namespace handler.
func NewNamespaceHandler(namespaceKey string) *NamespaceHandler {
return &NamespaceHandler{
namespaceKey: namespaceKey,
}
}