2022-09-05 03:06:08 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-06-27 10:56:41 -04:00
|
|
|
package node
|
|
|
|
|
2022-06-28 05:53:10 -04:00
|
|
|
import (
|
2022-07-18 10:37:59 -04:00
|
|
|
"errors"
|
2022-06-28 05:53:10 -04:00
|
|
|
"regexp"
|
2022-06-27 10:56:41 -04:00
|
|
|
|
2023-01-04 13:04:28 -05:00
|
|
|
updatev1alpha1 "github.com/edgelesssys/constellation/v2/operators/constellation-node-operator/v2/api/v1alpha1"
|
2022-06-28 05:53:10 -04:00
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
|
|
)
|
|
|
|
|
2022-07-18 10:37:59 -04:00
|
|
|
const controlPlaneRoleLabel = "node-role.kubernetes.io/control-plane"
|
|
|
|
|
2022-06-28 05:53:10 -04:00
|
|
|
var reservedHostRegex = regexp.MustCompile(`^(.+\.|)(kubernetes|k8s)\.io(/.*)?$`)
|
|
|
|
|
|
|
|
// Ready checks if a kubernetes node has the `NodeReady` condition set to true.
|
2022-06-27 10:56:41 -04:00
|
|
|
func Ready(node *corev1.Node) bool {
|
|
|
|
for _, cond := range node.Status.Conditions {
|
|
|
|
if cond.Type == corev1.NodeReady {
|
2022-06-28 05:53:10 -04:00
|
|
|
return cond.Status == corev1.ConditionTrue
|
2022-06-27 10:56:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2022-06-28 05:53:10 -04:00
|
|
|
|
2022-07-18 10:37:59 -04:00
|
|
|
// VPCIP returns the VPC IP of a node.
|
|
|
|
func VPCIP(node *corev1.Node) (string, error) {
|
|
|
|
for _, addr := range node.Status.Addresses {
|
|
|
|
if addr.Type == corev1.NodeInternalIP {
|
|
|
|
return addr.Address, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "", errors.New("no VPC IP found")
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsControlPlaneNode returns true if the node is a control plane node.
|
|
|
|
func IsControlPlaneNode(node *corev1.Node) bool {
|
|
|
|
_, ok := node.Labels[controlPlaneRoleLabel]
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2022-06-28 05:53:10 -04:00
|
|
|
// FindPending searches for a pending node that matches a node.
|
|
|
|
// The pending node has to have the goal to join the cluster and be reported as ready be the CSP.
|
|
|
|
// if the node is not found, nil is returned.
|
|
|
|
func FindPending(pendingNodes []updatev1alpha1.PendingNode, node *corev1.Node) *updatev1alpha1.PendingNode {
|
|
|
|
if node == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
for _, pendingNode := range pendingNodes {
|
|
|
|
if pendingNode.Spec.Goal == updatev1alpha1.NodeGoalJoin && pendingNode.Spec.NodeName == node.Name && pendingNode.Status.CSPNodeState == updatev1alpha1.NodeStateReady {
|
|
|
|
return &pendingNode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FilterLabels removes reserved node labels from a map of labels.
|
|
|
|
// reference: https://kubernetes.io/docs/reference/labels-annotations-taints/ .
|
|
|
|
func FilterLabels(labels map[string]string) map[string]string {
|
|
|
|
result := make(map[string]string)
|
|
|
|
for key, val := range labels {
|
|
|
|
if reservedHostRegex.MatchString(key) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
result[key] = val
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|