mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-22 20:19:00 +00:00
133 lines
2.8 KiB
Go
133 lines
2.8 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"k8s.io/utils/net"
|
|
)
|
|
|
|
// Color is given its own type for safe function signatures
|
|
type Color string
|
|
|
|
// Color codes interpreted by the terminal
|
|
// NOTE: all codes must be of the same length or they will throw off the field alignment of tabwriter
|
|
const (
|
|
ResetText Color = "\x1b[0000m"
|
|
BrightText = "\x1b[0001m"
|
|
RedText = "\x1b[0031m"
|
|
GreenText = "\x1b[0032m"
|
|
YellowText = "\x1b[0033m"
|
|
BlueText = "\x1b[0034m"
|
|
MagentaText = "\x1b[0035m"
|
|
CyanText = "\x1b[0036m"
|
|
WhiteText = "\x1b[0037m"
|
|
DefaultText = "\x1b[0039m"
|
|
BrightRedText = "\x1b[1;31m"
|
|
BrightGreenText = "\x1b[1;32m"
|
|
BrightYellowText = "\x1b[1;33m"
|
|
BrightBlueText = "\x1b[1;34m"
|
|
BrightMagentaText = "\x1b[1;35m"
|
|
BrightCyanText = "\x1b[1;36m"
|
|
BrightWhiteText = "\x1b[1;37m"
|
|
)
|
|
|
|
var colorsToTextColor = map[string]Color{
|
|
"yellow": YellowText,
|
|
"green": GreenText,
|
|
"red": RedText,
|
|
}
|
|
|
|
var SkipColor bool
|
|
|
|
// Color implements the Stringer interface for interoperability with string
|
|
func (c *Color) String() string {
|
|
return string(*c)
|
|
}
|
|
|
|
func Paint(color Color, value string) string {
|
|
if SkipColor {
|
|
return value
|
|
}
|
|
return fmt.Sprintf("%v%v%v", color, value, ResetText)
|
|
}
|
|
|
|
func PaintForState(text, state string) string {
|
|
|
|
c := ColorForState(state)
|
|
if c != "" {
|
|
return Paint(colorsToTextColor[c], text)
|
|
}
|
|
|
|
return text
|
|
}
|
|
|
|
func ColorForState(state string) string {
|
|
switch state {
|
|
case "DONOR", "JOINER", "DESYNCED":
|
|
return "yellow"
|
|
case "SYNCED":
|
|
return "green"
|
|
case "CLOSED", "NON-PRIMARY":
|
|
return "red"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func SliceContains(s []string, str string) bool {
|
|
for _, v := range s {
|
|
if v == str {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func SliceMergeDeduplicate(s, s2 []string) []string {
|
|
for _, str := range s2 {
|
|
if !SliceContains(s, str) {
|
|
s = append(s, str)
|
|
}
|
|
}
|
|
return s
|
|
}
|
|
|
|
// StringsReplaceReversed is similar to strings.Replace, but replacing the
|
|
// right-most elements instead of left-most
|
|
func StringsReplaceReversed(s, old, new string, n int) string {
|
|
|
|
s2 := s
|
|
stop := len(s)
|
|
|
|
for i := 0; i < n; i++ {
|
|
stop = strings.LastIndex(s[:stop], old)
|
|
|
|
s2 = (s[:stop]) + new + s2[stop+len(old):]
|
|
}
|
|
return s2
|
|
}
|
|
|
|
func UUIDToShortUUID(uuid string) string {
|
|
split := strings.Split(uuid, "-")
|
|
if len(split) != 5 {
|
|
return uuid
|
|
}
|
|
return split[0] + "-" + split[3]
|
|
}
|
|
|
|
// ShortNodeName helps reducing the node name when it is the default value (node hostname)
|
|
// It only keeps the top-level domain
|
|
func ShortNodeName(s string) string {
|
|
// short enough
|
|
if len(s) < 10 {
|
|
return s
|
|
}
|
|
// for the rare case of having IPs set as node names
|
|
if net.IsIPv4String(s) {
|
|
return s
|
|
}
|
|
before, _, _ := strings.Cut(s, ".")
|
|
return before
|
|
}
|