@@ -3,12 +3,16 @@ package ping
33import (
44 "context"
55
6- "github.com/pluralsh/deployment-operator/pkg/client "
6+ "github.com/Masterminds/semver/v3 "
77 "github.com/samber/lo"
88 corev1 "k8s.io/api/core/v1"
99 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1010 "k8s.io/client-go/discovery"
11+ "k8s.io/client-go/kubernetes"
12+ "k8s.io/klog/v2"
1113 "k8s.io/kubectl/pkg/cmd/util"
14+
15+ "github.com/pluralsh/deployment-operator/pkg/client"
1216)
1317
1418type Pinger struct {
@@ -28,27 +32,66 @@ func New(console client.Client, discovery *discovery.DiscoveryClient, factory ut
2832func (p * Pinger ) Ping () error {
2933 info , err := p .discoveryClient .ServerVersion ()
3034 if err != nil {
35+ klog .ErrorS (err , "failed to get server version" )
3136 return err
3237 }
3338
3439 cs , err := p .factory .KubernetesClientSet ()
3540 if err != nil {
41+ klog .ErrorS (err , "failed to create kubernetes clientset" )
3642 return nil
3743 }
3844
39- podNames := []string {}
45+ var podNames []string
4046 // can find some distro information by checking what's running in kube-system
41- if pods , err := cs .CoreV1 ().Pods ("kube-system" ).List (context .TODO (), metav1.ListOptions {}); err == nil {
47+ if pods , err := cs .CoreV1 ().Pods ("kube-system" ).List (context .Background (), metav1.ListOptions {}); err == nil {
4248 podNames = lo .Map (pods .Items , func (pod corev1.Pod , ind int ) string {
4349 return pod .Name
4450 })
4551 }
4652
47- attrs := pingAttributes (info , podNames )
53+ minKubeletVersion := p .minimumKubeletVersion (cs )
54+
55+ attrs := pingAttributes (info , podNames , minKubeletVersion )
4856 if err := p .consoleClient .PingCluster (attrs ); err != nil {
4957 attrs .Distro = nil
5058 return p .consoleClient .PingCluster (attrs ) // fallback to no distro to support old console servers
5159 }
5260
5361 return nil
5462}
63+
64+ // minimumKubeletVersion tries to scrape a minimum kubelet version across all nodes in the cluster.
65+ // It is expected that the kubelet will report to the API a valid SemVer-ish version.
66+ // If no parsable version is found across all nodes, nil will be returned.
67+ func (p * Pinger ) minimumKubeletVersion (client * kubernetes.Clientset ) * string {
68+ nodes , err := client .CoreV1 ().Nodes ().List (context .Background (), metav1.ListOptions {})
69+ if err != nil {
70+ klog .ErrorS (err , "failed to list nodes" )
71+ return nil
72+ }
73+
74+ minKubeletVersion := new (semver.Version )
75+ for _ , node := range nodes .Items {
76+ kubeletVersion , _ := semver .NewVersion (node .Status .NodeInfo .KubeletVersion )
77+ if kubeletVersion == nil {
78+ continue
79+ }
80+
81+ // Initialize with first correctly parsed version
82+ if len (minKubeletVersion .Original ()) == 0 {
83+ minKubeletVersion = kubeletVersion
84+ continue
85+ }
86+
87+ if kubeletVersion .LessThan (minKubeletVersion ) {
88+ minKubeletVersion = kubeletVersion
89+ }
90+ }
91+
92+ if len (minKubeletVersion .Original ()) == 0 {
93+ return nil
94+ }
95+
96+ return lo .ToPtr (minKubeletVersion .Original ())
97+ }
0 commit comments