Refactor into RenderAgent and ApplyAgent
This commit is contained in:
@@ -8,9 +8,18 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type kubeVersion struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
}
|
||||
|
||||
func ValidateNodeIPAndAPIServerReachability(ctx context.Context, nct *NodeContext) error {
|
||||
requireLocalIP := func(wantedIP string) error {
|
||||
wantedIP = strings.TrimSpace(wantedIP)
|
||||
@@ -189,3 +198,116 @@ func CheckForVersionSkew(ctx context.Context, nctx *NodeContext) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func versionEq(a, b string) bool {
|
||||
return normalizeKubeVersion(a) == normalizeKubeVersion(b)
|
||||
}
|
||||
|
||||
func normalizeKubeVersion(v string) string {
|
||||
v = strings.TrimSpace(v)
|
||||
if v == "" {
|
||||
return ""
|
||||
}
|
||||
if !strings.HasPrefix(v, "v") {
|
||||
v = "v" + v
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func parseKubeVersion(s string) (kubeVersion, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimPrefix(s, "v")
|
||||
|
||||
var v kubeVersion
|
||||
n, err := fmt.Sscanf(s, "%d.%d.%d", &v.Major, &v.Minor, &v.Patch)
|
||||
// Accepts "1.29" or "1.29.3"
|
||||
if err != nil || n < 2 {
|
||||
return kubeVersion{}, fmt.Errorf("invalid kubernetes version %q", s)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Control-plane: keep this strict.
|
||||
// Accept same version, or a one-minor step where the node binary is newer than the current cluster.
|
||||
// That covers normal control-plane upgrade flow but blocks nonsense.
|
||||
func isSupportedControlPlaneSkew(clusterVersion, nodeVersion string) bool {
|
||||
cv, err := parseKubeVersion(clusterVersion)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
nv, err := parseKubeVersion(nodeVersion)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if cv.Major != nv.Major {
|
||||
return false
|
||||
}
|
||||
if cv.Minor == nv.Minor {
|
||||
return true
|
||||
}
|
||||
if nv.Minor == cv.Minor+1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Worker: kubelet generally must not be newer than the apiserver.
|
||||
// Older kubelets are allowed within supported skew range.
|
||||
// Your requirement says unsupported worker skew should still proceed, so this
|
||||
// only classifies support status and must NOT be used to block this function.
|
||||
func isSupportedWorkerSkew(clusterVersion, nodeVersion string) bool {
|
||||
cv, err := parseKubeVersion(clusterVersion)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
nv, err := parseKubeVersion(nodeVersion)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if cv.Major != nv.Major {
|
||||
return false
|
||||
}
|
||||
|
||||
// kubelet newer than apiserver => unsupported
|
||||
if nv.Minor > cv.Minor {
|
||||
return false
|
||||
}
|
||||
|
||||
// kubelet up to 3 minors older than apiserver => supported
|
||||
if cv.Minor-nv.Minor <= 3 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getServerVersion(ctx context.Context, kubeconfigPath string) (string, error) {
|
||||
restCfg, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("build kubeconfig %s: %w", kubeconfigPath, err)
|
||||
}
|
||||
|
||||
// Keep this short. This is a probe, not a long-running client.
|
||||
restCfg.Timeout = 5 * time.Second
|
||||
|
||||
clientset, err := kubernetes.NewForConfig(restCfg)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("create clientset: %w", err)
|
||||
}
|
||||
|
||||
disc := clientset.Discovery()
|
||||
return discoverServerVersion(ctx, disc)
|
||||
}
|
||||
|
||||
func discoverServerVersion(ctx context.Context, disc discovery.DiscoveryInterface) (string, error) {
|
||||
info, err := disc.ServerVersion()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if info == nil || strings.TrimSpace(info.GitVersion) == "" {
|
||||
return "", errors.New("server version is empty")
|
||||
}
|
||||
return normalizeKubeVersion(info.GitVersion), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user