-
Notifications
You must be signed in to change notification settings - Fork 0
/
podspec.go
124 lines (97 loc) · 4.34 KB
/
podspec.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
package analysis
import (
"fmt"
"github.com/gonum/graph"
osgraph "github.com/openshift/origin/pkg/api/graph"
kubeedges "github.com/openshift/origin/pkg/api/kubegraph"
kubegraph "github.com/openshift/origin/pkg/api/kubegraph/nodes"
)
const (
UnmountableSecretWarning = "UnmountableSecret"
MissingSecretWarning = "MissingSecret"
)
// FindUnmountableSecrets inspects all PodSpecs for any Secret reference that isn't listed as mountable by the referenced ServiceAccount
func FindUnmountableSecrets(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
markers := []osgraph.Marker{}
for _, uncastPodSpecNode := range g.NodesByKind(kubegraph.PodSpecNodeKind) {
podSpecNode := uncastPodSpecNode.(*kubegraph.PodSpecNode)
unmountableSecrets := CheckForUnmountableSecrets(g, podSpecNode)
topLevelNode := osgraph.GetTopLevelContainerNode(g, podSpecNode)
topLevelString := f.ResourceName(topLevelNode)
saString := "MISSING_SA"
saNodes := g.SuccessorNodesByEdgeKind(podSpecNode, kubeedges.ReferencedServiceAccountEdgeKind)
if len(saNodes) > 0 {
saString = f.ResourceName(saNodes[0])
}
for _, unmountableSecret := range unmountableSecrets {
markers = append(markers, osgraph.Marker{
Node: podSpecNode,
RelatedNodes: []graph.Node{unmountableSecret},
Severity: osgraph.WarningSeverity,
Key: UnmountableSecretWarning,
Message: fmt.Sprintf("%s is attempting to mount a secret %s disallowed by %s",
topLevelString, f.ResourceName(unmountableSecret), saString),
})
}
}
return markers
}
// FindMissingSecrets inspects all PodSpecs for any Secret reference that is a synthetic node (not a pre-existing node in the graph)
func FindMissingSecrets(g osgraph.Graph, f osgraph.Namer) []osgraph.Marker {
markers := []osgraph.Marker{}
for _, uncastPodSpecNode := range g.NodesByKind(kubegraph.PodSpecNodeKind) {
podSpecNode := uncastPodSpecNode.(*kubegraph.PodSpecNode)
missingSecrets := CheckMissingMountedSecrets(g, podSpecNode)
topLevelNode := osgraph.GetTopLevelContainerNode(g, podSpecNode)
topLevelString := f.ResourceName(topLevelNode)
for _, missingSecret := range missingSecrets {
markers = append(markers, osgraph.Marker{
Node: podSpecNode,
RelatedNodes: []graph.Node{missingSecret},
Severity: osgraph.WarningSeverity,
Key: UnmountableSecretWarning,
Message: fmt.Sprintf("%s is attempting to mount a missing secret %s",
topLevelString, f.ResourceName(missingSecret)),
})
}
}
return markers
}
// CheckForUnmountableSecrets checks to be sure that all the referenced secrets are mountable (by service account)
func CheckForUnmountableSecrets(g osgraph.Graph, podSpecNode *kubegraph.PodSpecNode) []*kubegraph.SecretNode {
saNodes := g.SuccessorNodesByNodeAndEdgeKind(podSpecNode, kubegraph.ServiceAccountNodeKind, kubeedges.ReferencedServiceAccountEdgeKind)
saMountableSecrets := []*kubegraph.SecretNode{}
if len(saNodes) > 0 {
saNode := saNodes[0].(*kubegraph.ServiceAccountNode)
for _, secretNode := range g.SuccessorNodesByNodeAndEdgeKind(saNode, kubegraph.SecretNodeKind, kubeedges.MountableSecretEdgeKind) {
saMountableSecrets = append(saMountableSecrets, secretNode.(*kubegraph.SecretNode))
}
}
unmountableSecrets := []*kubegraph.SecretNode{}
for _, uncastMountedSecretNode := range g.SuccessorNodesByNodeAndEdgeKind(podSpecNode, kubegraph.SecretNodeKind, kubeedges.MountedSecretEdgeKind) {
mountedSecretNode := uncastMountedSecretNode.(*kubegraph.SecretNode)
mountable := false
for _, mountableSecretNode := range saMountableSecrets {
if mountableSecretNode == mountedSecretNode {
mountable = true
break
}
}
if !mountable {
unmountableSecrets = append(unmountableSecrets, mountedSecretNode)
continue
}
}
return unmountableSecrets
}
// CheckMissingMountedSecrets checks to be sure that all the referenced secrets are present (not synthetic)
func CheckMissingMountedSecrets(g osgraph.Graph, podSpecNode *kubegraph.PodSpecNode) []*kubegraph.SecretNode {
missingSecrets := []*kubegraph.SecretNode{}
for _, uncastMountedSecretNode := range g.SuccessorNodesByNodeAndEdgeKind(podSpecNode, kubegraph.SecretNodeKind, kubeedges.MountedSecretEdgeKind) {
mountedSecretNode := uncastMountedSecretNode.(*kubegraph.SecretNode)
if !mountedSecretNode.Found() {
missingSecrets = append(missingSecrets, mountedSecretNode)
}
}
return missingSecrets
}