-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
container.go
104 lines (89 loc) 路 2.78 KB
/
container.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
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s
package xray
import (
"context"
"fmt"
"github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/dao"
"github.com/derailed/k9s/internal/render"
"github.com/rs/zerolog/log"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
// Container represents an xray renderer.
type Container struct{}
// Render renders an xray node.
func (c *Container) Render(ctx context.Context, ns string, o interface{}) error {
co, ok := o.(render.ContainerRes)
if !ok {
return fmt.Errorf("expected ContainerRes, but got %T", o)
}
f, ok := ctx.Value(internal.KeyFactory).(dao.Factory)
if !ok {
return fmt.Errorf("no factory found in context")
}
root := NewTreeNode("containers", client.FQN(ns, co.Container.Name))
parent, ok := ctx.Value(KeyParent).(*TreeNode)
if !ok {
return fmt.Errorf("Expecting a TreeNode but got %T", ctx.Value(KeyParent))
}
pns, _ := client.Namespaced(parent.ID)
c.envRefs(f, root, pns, co.Container)
parent.Add(root)
return nil
}
func (c *Container) envRefs(f dao.Factory, parent *TreeNode, ns string, co *v1.Container) {
for _, e := range co.Env {
if e.ValueFrom == nil {
continue
}
c.secretRefs(f, parent, ns, e.ValueFrom.SecretKeyRef)
c.configMapRefs(f, parent, ns, e.ValueFrom.ConfigMapKeyRef)
}
for _, e := range co.EnvFrom {
if e.ConfigMapRef != nil {
gvr, id := "v1/configmaps", client.FQN(ns, e.ConfigMapRef.Name)
addRef(f, parent, gvr, id, e.ConfigMapRef.Optional)
}
if e.SecretRef != nil {
gvr, id := "v1/secrets", client.FQN(ns, e.SecretRef.Name)
addRef(f, parent, gvr, id, e.SecretRef.Optional)
}
}
}
func (c *Container) secretRefs(f dao.Factory, parent *TreeNode, ns string, ref *v1.SecretKeySelector) {
if ref == nil {
return
}
gvr, id := "v1/secrets", client.FQN(ns, ref.LocalObjectReference.Name)
addRef(f, parent, gvr, id, ref.Optional)
}
func (c *Container) configMapRefs(f dao.Factory, parent *TreeNode, ns string, ref *v1.ConfigMapKeySelector) {
if ref == nil {
return
}
gvr, id := "v1/configmaps", client.FQN(ns, ref.LocalObjectReference.Name)
addRef(f, parent, gvr, id, ref.Optional)
}
// ----------------------------------------------------------------------------
// Helpers...
func addRef(f dao.Factory, parent *TreeNode, gvr, id string, optional *bool) {
if parent.Find(gvr, id) == nil {
n := NewTreeNode(gvr, id)
validate(f, n, optional)
parent.Add(n)
}
}
func validate(f dao.Factory, n *TreeNode, optional *bool) {
res, err := f.Get(n.GVR, n.ID, true, labels.Everything())
if err != nil || res == nil {
if optional == nil || !*optional {
log.Warn().Err(err).Msgf("Missing ref %q::%q", n.GVR, n.ID)
n.Extras[StatusKey] = MissingRefStatus
}
return
}
n.Extras[StatusKey] = OkStatus
}