Skip to content

Commit 74747cc

Browse files
committed
POC: block operator upgrade when detecting outdated vms
Signed-off-by: Daniel Sionov <[email protected]>
1 parent b974705 commit 74747cc

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

controllers/hyperconverged/hyperconverged_controller.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package hyperconverged
33
import (
44
"cmp"
55
"context"
6+
"crypto/tls"
67
"encoding/json"
78
"fmt"
9+
"io"
10+
"net/http"
811
"os"
912
"reflect"
13+
"regexp"
1014
"slices"
1115

1216
"github.com/blang/semver/v4"
@@ -336,6 +340,8 @@ func (r *ReconcileHyperConverged) Reconcile(ctx context.Context, request reconci
336340
return result, err
337341
}
338342

343+
r.EvaluateUpgradeEligibility(hcoRequest)
344+
339345
if err = r.setOperatorUpgradeableStatus(hcoRequest); err != nil {
340346
return reconcile.Result{}, err
341347
}
@@ -1330,6 +1336,69 @@ func (r *ReconcileHyperConverged) deleteObj(req *common.HcoRequest, obj client.O
13301336
return removed, nil
13311337
}
13321338

1339+
func (r *ReconcileHyperConverged) EvaluateUpgradeEligibility(req *common.HcoRequest) error {
1340+
podList := &corev1.PodList{}
1341+
listOpts := []client.ListOption{
1342+
client.InNamespace(req.Namespace),
1343+
client.MatchingLabels{"kubevirt.io": "virt-controller"},
1344+
}
1345+
1346+
if err := r.client.List(req.Ctx, podList, listOpts...); err != nil {
1347+
req.Logger.Info("Failed to list virt-controller pods", "namespace", req.Namespace, "error", err)
1348+
return fmt.Errorf("failed to list virt-controller pods: %w", err)
1349+
}
1350+
1351+
if len(podList.Items) == 0 {
1352+
req.Logger.Info("No virt-controller pods found", "namespace", req.Namespace)
1353+
return nil
1354+
}
1355+
1356+
httpClient := &http.Client{
1357+
Transport: &http.Transport{
1358+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
1359+
},
1360+
}
1361+
1362+
for _, pod := range podList.Items {
1363+
if pod.Status.PodIP == "" {
1364+
continue
1365+
}
1366+
metricsURL := fmt.Sprintf("https://%s:%d/metrics", pod.Status.PodIP, 8443)
1367+
1368+
resp, err := httpClient.Get(metricsURL)
1369+
if err != nil {
1370+
req.Logger.Info("Failed to query metrics from pod", "pod", pod.Name, "error", err)
1371+
continue
1372+
}
1373+
1374+
if resp.StatusCode != http.StatusOK {
1375+
req.Logger.Info("Metrics endpoint returned non-200 status", "pod", pod.Name, "status", resp.StatusCode)
1376+
resp.Body.Close()
1377+
continue
1378+
}
1379+
1380+
body, err := io.ReadAll(resp.Body)
1381+
resp.Body.Close()
1382+
if err != nil {
1383+
req.Logger.Info("Failed to read metrics response from pod", "pod", pod.Name, "error", err)
1384+
continue
1385+
}
1386+
1387+
virtMetrics := string(body)
1388+
1389+
req.Logger.Info("Metrics data from pod", "pod", pod.Name, "metrics", virtMetrics)
1390+
1391+
rhel8Regex := regexp.MustCompile(`.*rhel8.*`)
1392+
if rhel8Regex.MatchString(virtMetrics) {
1393+
req.Logger.Info("Detected outdated machine type in metrics", "pod", pod.Name, "matched", rhel8Regex.FindString(virtMetrics))
1394+
req.Upgradeable = false
1395+
return nil
1396+
}
1397+
}
1398+
1399+
return nil
1400+
}
1401+
13331402
func removeOldQuickStartGuides(req *common.HcoRequest, cl client.Client, requiredQSList []string) {
13341403
existingQSList := &consolev1.ConsoleQuickStartList{}
13351404
req.Logger.Info("reading quickstart guides")

0 commit comments

Comments
 (0)