...

Source file src/edge-infra.dev/pkg/edge/webhooks/edge-injector/node_webhook.go

Documentation: edge-infra.dev/pkg/edge/webhooks/edge-injector

     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  // checkNodeSecret is needed due to how reconciliation can trigger before new version of the secret is created
    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  	// convert the custom label key to be a k8s safe name
    83  	// custom.node.com/label_key: val
    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