k9s/internal/model1/helpers.go

167 lines
3.1 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of K9s
package model1
import (
"fmt"
"math"
"sort"
"strings"
"github.com/fvbommel/sortorder"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
func Hydrate(ns string, oo []runtime.Object, rr Rows, re Renderer) error {
for i, o := range oo {
if err := re.Render(o, ns, &rr[i]); err != nil {
return err
}
}
return nil
}
func GenericHydrate(ns string, table *metav1.Table, rr Rows, re Renderer) error {
gr, ok := re.(Generic)
if !ok {
return fmt.Errorf("expecting generic renderer but got %T", re)
}
gr.SetTable(ns, table)
for i, row := range table.Rows {
if err := gr.Render(row, ns, &rr[i]); err != nil {
return err
}
}
return nil
}
// IsValid returns true if resource is valid, false otherwise.
func IsValid(ns string, h Header, r Row) bool {
if len(r.Fields) == 0 {
return true
}
idx, ok := h.IndexOf("VALID", true)
if !ok || idx >= len(r.Fields) {
return true
}
return strings.TrimSpace(r.Fields[idx]) == "" || strings.ToLower(strings.TrimSpace(r.Fields[idx])) == "true"
}
func sortLabels(m map[string]string) (keys, vals []string) {
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
vals = append(vals, m[k])
}
return
}
// Converts labels string to map.
func labelize(labels string) map[string]string {
ll := strings.Split(labels, ",")
data := make(map[string]string, len(ll))
for _, l := range ll {
tokens := strings.Split(l, "=")
if len(tokens) == 2 {
data[tokens[0]] = tokens[1]
}
}
return data
}
func durationToSeconds(duration string) int64 {
if len(duration) == 0 {
return 0
}
if duration == NAValue {
return math.MaxInt64
}
num := make([]rune, 0, 5)
var n, m int64
for _, r := range duration {
switch r {
case 'y':
m = 365 * 24 * 60 * 60
case 'd':
m = 24 * 60 * 60
case 'h':
m = 60 * 60
case 'm':
m = 60
case 's':
m = 1
default:
num = append(num, r)
continue
}
n, num = n+runesToNum(num)*m, num[:0]
}
return n
}
func runesToNum(rr []rune) int64 {
var r int64
var m int64 = 1
for i := len(rr) - 1; i >= 0; i-- {
v := int64(rr[i] - '0')
r += v * m
m *= 10
}
return r
}
func capacityToNumber(capacity string) int64 {
quantity := resource.MustParse(capacity)
return quantity.Value()
}
// Less return true if c1 <= c2.
func Less(isNumber, isDuration, isCapacity bool, id1, id2, v1, v2 string) bool {
var less bool
switch {
case isNumber:
less = lessNumber(v1, v2)
case isDuration:
less = lessDuration(v1, v2)
case isCapacity:
less = lessCapacity(v1, v2)
default:
less = sortorder.NaturalLess(v1, v2)
}
if v1 == v2 {
return sortorder.NaturalLess(id1, id2)
}
return less
}
func lessDuration(s1, s2 string) bool {
d1, d2 := durationToSeconds(s1), durationToSeconds(s2)
return d1 <= d2
}
func lessCapacity(s1, s2 string) bool {
c1, c2 := capacityToNumber(s1), capacityToNumber(s2)
return c1 <= c2
}
func lessNumber(s1, s2 string) bool {
v1, v2 := strings.ReplaceAll(s1, ",", ""), strings.ReplaceAll(s2, ",", "")
return sortorder.NaturalLess(v1, v2)
}