1 package edgeinjector
2
3 import (
4 "context"
5 "fmt"
6 "strings"
7
8 "k8s.io/apimachinery/pkg/api/errors"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10
11 corev1 "k8s.io/api/core/v1"
12 "sigs.k8s.io/controller-runtime/pkg/client"
13
14 "k8s.io/apimachinery/pkg/runtime"
15
16 "edge-infra.dev/pkg/edge/api/utils"
17 "edge-infra.dev/pkg/edge/controllers/envctl/pkg/nameutils"
18 "edge-infra.dev/pkg/lib/fog"
19 v1ien "edge-infra.dev/pkg/sds/ien/k8s/apis/v1"
20 )
21
22 type NodeField string
23
24 const (
25 Hostname = NodeField("NODE_HOSTNAME")
26 Lane = NodeField("NODE_LANE")
27 Role = NodeField("NODE_ROLE")
28 Class = NodeField("NODE_CLASS")
29 NodeUID = NodeField("NODE_UID")
30 )
31
32 type NodeWebhook struct {
33 client.Client
34 }
35
36 func (c *NodeWebhook) Default(ctx context.Context, obj runtime.Object) error {
37 log := fog.FromContext(ctx).WithValues("name", "NodeWebhook")
38
39 pod, ok := obj.(*corev1.Pod)
40 if !ok {
41 err := fmt.Errorf("expected a Pod but got a %T", obj)
42 log.Error(err, "not a pod")
43 return err
44 }
45
46 log = log.WithValues("pod", client.ObjectKeyFromObject(pod))
47
48 if SecretLabelValue(pod, NodeSecret) != "" {
49 log.Info("node secret label already exists", client.ObjectKeyFromObject(pod))
50 return nil
51 }
52
53 ctx = fog.IntoContext(ctx, log)
54
55 InjectSecret(ctx, pod, NodeSecret)
56
57 log.Info("successfully injected node secret environment variables")
58
59 return nil
60 }
61
62
63 func checkNodeSecret(s *corev1.Secret) error {
64 requiredFields := []NodeField{Hostname, Lane, NodeUID, Role, Class}
65 for _, field := range requiredFields {
66 if _, ok := s.Data[string(field)]; !ok {
67 return errors.NewNotFound(corev1.Resource("secret"),
68 fmt.Sprintf("secret: %s, missing field %s", s.Name, field))
69 }
70 }
71 return nil
72 }
73
74 func BuildNodeSecret(pod *corev1.Pod, info *nameutils.NodeInfo, customLabels map[string]string, secretName string) *corev1.Secret {
75 customLabelsEnvs := map[string]string{
76 string(Hostname): info.Hostname,
77 string(Lane): info.Lane,
78 string(NodeUID): info.UID,
79 string(Role): string(info.Role),
80 string(Class): string(info.Class),
81 }
82
83
84 for key, val := range customLabels {
85 labelKey := strings.TrimPrefix(key, fmt.Sprintf(v1ien.CustomNodeLabel, ""))
86 customLabelsEnvs[utils.ToENVName(labelKey)] = val
87 }
88 return &corev1.Secret{
89 TypeMeta: metav1.TypeMeta{
90 APIVersion: "v1",
91 Kind: "Secret",
92 },
93 ObjectMeta: metav1.ObjectMeta{
94 Name: secretName,
95 Namespace: pod.Namespace,
96 OwnerReferences: []metav1.OwnerReference{
97 *metav1.NewControllerRef(
98 pod,
99 corev1.SchemeGroupVersion.WithKind("Pod"),
100 ),
101 },
102 },
103 StringData: customLabelsEnvs,
104 }
105 }
106
107 func GetNodeCustomLabels(node *corev1.Node) (map[string]string, error) {
108 customLabels := make(map[string]string, 0)
109 labels := node.GetLabels()
110 if len(labels) == 0 {
111 return customLabels, nameutils.ErrMissingNodeLabels
112 }
113 for k, v := range labels {
114 if IsCustomLabel(k) {
115 customLabels[k] = v
116 }
117 }
118 return customLabels, nil
119 }
120
View as plain text