mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-04-26 10:18:50 +02:00
Initial v1.0.0 commit
This commit is contained in:
302
vendor/github.com/rancher/wrangler/pkg/data/convert/convert.go
generated
vendored
Normal file
302
vendor/github.com/rancher/wrangler/pkg/data/convert/convert.go
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func Singular(value interface{}) interface{} {
|
||||
if slice, ok := value.([]string); ok {
|
||||
if len(slice) == 0 {
|
||||
return nil
|
||||
}
|
||||
return slice[0]
|
||||
}
|
||||
if slice, ok := value.([]interface{}); ok {
|
||||
if len(slice) == 0 {
|
||||
return nil
|
||||
}
|
||||
return slice[0]
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func ToStringNoTrim(value interface{}) string {
|
||||
if t, ok := value.(time.Time); ok {
|
||||
return t.Format(time.RFC3339)
|
||||
}
|
||||
single := Singular(value)
|
||||
if single == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprint(single)
|
||||
}
|
||||
|
||||
func ToString(value interface{}) string {
|
||||
return strings.TrimSpace(ToStringNoTrim(value))
|
||||
}
|
||||
|
||||
func ToTimestamp(value interface{}) (int64, error) {
|
||||
str := ToString(value)
|
||||
if str == "" {
|
||||
return 0, errors.New("invalid date")
|
||||
}
|
||||
t, err := time.Parse(time.RFC3339, str)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return t.UnixNano() / 1000000, nil
|
||||
}
|
||||
|
||||
func ToBool(value interface{}) bool {
|
||||
value = Singular(value)
|
||||
|
||||
b, ok := value.(bool)
|
||||
if ok {
|
||||
return b
|
||||
}
|
||||
|
||||
str := strings.ToLower(ToString(value))
|
||||
return str == "true" || str == "t" || str == "yes" || str == "y"
|
||||
}
|
||||
|
||||
func ToNumber(value interface{}) (int64, error) {
|
||||
value = Singular(value)
|
||||
|
||||
i, ok := value.(int64)
|
||||
if ok {
|
||||
return i, nil
|
||||
}
|
||||
f, ok := value.(float64)
|
||||
if ok {
|
||||
return int64(f), nil
|
||||
}
|
||||
if n, ok := value.(json.Number); ok {
|
||||
i, err := n.Int64()
|
||||
if err == nil {
|
||||
return i, nil
|
||||
}
|
||||
f, err := n.Float64()
|
||||
return int64(f), err
|
||||
}
|
||||
return strconv.ParseInt(ToString(value), 10, 64)
|
||||
}
|
||||
|
||||
func ToFloat(value interface{}) (float64, error) {
|
||||
value = Singular(value)
|
||||
|
||||
f64, ok := value.(float64)
|
||||
if ok {
|
||||
return f64, nil
|
||||
}
|
||||
|
||||
f32, ok := value.(float32)
|
||||
if ok {
|
||||
return float64(f32), nil
|
||||
}
|
||||
|
||||
if n, ok := value.(json.Number); ok {
|
||||
i, err := n.Int64()
|
||||
if err == nil {
|
||||
return float64(i), nil
|
||||
}
|
||||
f, err := n.Float64()
|
||||
return float64(f), err
|
||||
}
|
||||
return strconv.ParseFloat(ToString(value), 64)
|
||||
}
|
||||
|
||||
func Capitalize(s string) string {
|
||||
if len(s) <= 1 {
|
||||
return strings.ToUpper(s)
|
||||
}
|
||||
|
||||
return strings.ToUpper(s[:1]) + s[1:]
|
||||
}
|
||||
|
||||
func Uncapitalize(s string) string {
|
||||
if len(s) <= 1 {
|
||||
return strings.ToLower(s)
|
||||
}
|
||||
|
||||
return strings.ToLower(s[:1]) + s[1:]
|
||||
}
|
||||
|
||||
func LowerTitle(input string) string {
|
||||
runes := []rune(input)
|
||||
for i := 0; i < len(runes); i++ {
|
||||
if unicode.IsUpper(runes[i]) &&
|
||||
(i == 0 ||
|
||||
i == len(runes)-1 ||
|
||||
unicode.IsUpper(runes[i+1])) {
|
||||
runes[i] = unicode.ToLower(runes[i])
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
func IsEmptyValue(v interface{}) bool {
|
||||
if v == nil || v == "" || v == 0 || v == false {
|
||||
return true
|
||||
}
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
return len(m) == 0
|
||||
}
|
||||
if s, ok := v.([]interface{}); ok {
|
||||
return len(s) == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ToMapInterface(obj interface{}) map[string]interface{} {
|
||||
v, _ := obj.(map[string]interface{})
|
||||
return v
|
||||
}
|
||||
|
||||
func ToInterfaceSlice(obj interface{}) []interface{} {
|
||||
if v, ok := obj.([]interface{}); ok {
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ToMapSlice(obj interface{}) []map[string]interface{} {
|
||||
if v, ok := obj.([]map[string]interface{}); ok {
|
||||
return v
|
||||
}
|
||||
vs, _ := obj.([]interface{})
|
||||
var result []map[string]interface{}
|
||||
for _, item := range vs {
|
||||
if v, ok := item.(map[string]interface{}); ok {
|
||||
result = append(result, v)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func ToStringSlice(data interface{}) []string {
|
||||
if v, ok := data.([]string); ok {
|
||||
return v
|
||||
}
|
||||
if v, ok := data.([]interface{}); ok {
|
||||
var result []string
|
||||
for _, item := range v {
|
||||
result = append(result, ToString(item))
|
||||
}
|
||||
return result
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ToObj(data interface{}, into interface{}) error {
|
||||
bytes, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(bytes, into)
|
||||
}
|
||||
|
||||
func EncodeToMap(obj interface{}) (map[string]interface{}, error) {
|
||||
if m, ok := obj.(map[string]interface{}); ok {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
b, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string]interface{}{}
|
||||
dec := json.NewDecoder(bytes.NewBuffer(b))
|
||||
dec.UseNumber()
|
||||
return result, dec.Decode(&result)
|
||||
}
|
||||
|
||||
func ToJSONKey(str string) string {
|
||||
parts := strings.Split(str, "_")
|
||||
for i := 1; i < len(parts); i++ {
|
||||
parts[i] = strings.Title(parts[i])
|
||||
}
|
||||
|
||||
return strings.Join(parts, "")
|
||||
}
|
||||
|
||||
func ToYAMLKey(str string) string {
|
||||
var result []rune
|
||||
cap := false
|
||||
|
||||
for i, r := range []rune(str) {
|
||||
if i == 0 {
|
||||
if unicode.IsUpper(r) {
|
||||
cap = true
|
||||
}
|
||||
result = append(result, unicode.ToLower(r))
|
||||
continue
|
||||
}
|
||||
|
||||
if unicode.IsUpper(r) {
|
||||
if cap {
|
||||
result = append(result, unicode.ToLower(r))
|
||||
} else {
|
||||
result = append(result, '_', unicode.ToLower(r))
|
||||
}
|
||||
} else {
|
||||
cap = false
|
||||
result = append(result, r)
|
||||
}
|
||||
}
|
||||
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func ToArgKey(str string) string {
|
||||
var (
|
||||
result []rune
|
||||
input = []rune(str)
|
||||
)
|
||||
cap := false
|
||||
|
||||
for i := 0; i < len(input); i++ {
|
||||
r := input[i]
|
||||
if i == 0 {
|
||||
if unicode.IsUpper(r) {
|
||||
cap = true
|
||||
}
|
||||
result = append(result, unicode.ToLower(r))
|
||||
continue
|
||||
}
|
||||
|
||||
if unicode.IsUpper(r) {
|
||||
if cap {
|
||||
result = append(result, unicode.ToLower(r))
|
||||
} else if len(input) > i+2 &&
|
||||
unicode.IsUpper(input[i]) &&
|
||||
unicode.IsUpper(input[i+1]) &&
|
||||
unicode.IsUpper(input[i+2]) {
|
||||
result = append(result, '-',
|
||||
unicode.ToLower(input[i]),
|
||||
unicode.ToLower(input[i+1]),
|
||||
unicode.ToLower(input[i+2]))
|
||||
i += 2
|
||||
} else {
|
||||
result = append(result, '-', unicode.ToLower(r))
|
||||
}
|
||||
} else {
|
||||
cap = false
|
||||
result = append(result, r)
|
||||
}
|
||||
}
|
||||
|
||||
return "--" + string(result)
|
||||
}
|
||||
59
vendor/github.com/rancher/wrangler/pkg/data/data.go
generated
vendored
Normal file
59
vendor/github.com/rancher/wrangler/pkg/data/data.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"github.com/rancher/wrangler/pkg/data/convert"
|
||||
)
|
||||
|
||||
type List []map[string]interface{}
|
||||
|
||||
type Object map[string]interface{}
|
||||
|
||||
func New() Object {
|
||||
return map[string]interface{}{}
|
||||
}
|
||||
|
||||
func (o Object) Map(names ...string) Object {
|
||||
v := GetValueN(o, names...)
|
||||
m := convert.ToMapInterface(v)
|
||||
return m
|
||||
}
|
||||
|
||||
func (o Object) Slice(names ...string) (result []Object) {
|
||||
v := GetValueN(o, names...)
|
||||
for _, item := range convert.ToInterfaceSlice(v) {
|
||||
result = append(result, convert.ToMapInterface(item))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o Object) Values() (result []Object) {
|
||||
for k := range o {
|
||||
result = append(result, o.Map(k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o Object) String(names ...string) string {
|
||||
v := GetValueN(o, names...)
|
||||
return convert.ToString(v)
|
||||
}
|
||||
|
||||
func (o Object) StringSlice(names ...string) []string {
|
||||
v := GetValueN(o, names...)
|
||||
return convert.ToStringSlice(v)
|
||||
}
|
||||
|
||||
func (o Object) Set(key string, obj interface{}) {
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
o[key] = obj
|
||||
}
|
||||
|
||||
func (o Object) SetNested(obj interface{}, key ...string) {
|
||||
PutValue(o, obj, key...)
|
||||
}
|
||||
|
||||
func (o Object) Bool(key ...string) bool {
|
||||
return convert.ToBool(GetValueN(o, key...))
|
||||
}
|
||||
24
vendor/github.com/rancher/wrangler/pkg/data/merge.go
generated
vendored
Normal file
24
vendor/github.com/rancher/wrangler/pkg/data/merge.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
package data
|
||||
|
||||
func MergeMaps(base, overlay map[string]interface{}) map[string]interface{} {
|
||||
result := map[string]interface{}{}
|
||||
for k, v := range base {
|
||||
result[k] = v
|
||||
}
|
||||
for k, v := range overlay {
|
||||
if baseMap, overlayMap, bothMaps := bothMaps(result[k], v); bothMaps {
|
||||
v = MergeMaps(baseMap, overlayMap)
|
||||
}
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func bothMaps(left, right interface{}) (map[string]interface{}, map[string]interface{}, bool) {
|
||||
leftMap, ok := left.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, nil, false
|
||||
}
|
||||
rightMap, ok := right.(map[string]interface{})
|
||||
return leftMap, rightMap, ok
|
||||
}
|
||||
58
vendor/github.com/rancher/wrangler/pkg/data/values.go
generated
vendored
Normal file
58
vendor/github.com/rancher/wrangler/pkg/data/values.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package data
|
||||
|
||||
func RemoveValue(data map[string]interface{}, keys ...string) (interface{}, bool) {
|
||||
for i, key := range keys {
|
||||
if i == len(keys)-1 {
|
||||
val, ok := data[key]
|
||||
delete(data, key)
|
||||
return val, ok
|
||||
}
|
||||
data, _ = data[key].(map[string]interface{})
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func GetValueN(data map[string]interface{}, keys ...string) interface{} {
|
||||
val, _ := GetValue(data, keys...)
|
||||
return val
|
||||
}
|
||||
|
||||
func GetValue(data map[string]interface{}, keys ...string) (interface{}, bool) {
|
||||
for i, key := range keys {
|
||||
if i == len(keys)-1 {
|
||||
val, ok := data[key]
|
||||
return val, ok
|
||||
}
|
||||
data, _ = data[key].(map[string]interface{})
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func PutValue(data map[string]interface{}, val interface{}, keys ...string) {
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// This is so ugly
|
||||
for i, key := range keys {
|
||||
if i == len(keys)-1 {
|
||||
data[key] = val
|
||||
} else {
|
||||
newData, ok := data[key]
|
||||
if ok {
|
||||
newMap, ok := newData.(map[string]interface{})
|
||||
if ok {
|
||||
data = newMap
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
newMap := map[string]interface{}{}
|
||||
data[key] = newMap
|
||||
data = newMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
vendor/github.com/rancher/wrangler/pkg/genericcondition/condition.go
generated
vendored
Normal file
18
vendor/github.com/rancher/wrangler/pkg/genericcondition/condition.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package genericcondition
|
||||
|
||||
import v1 "k8s.io/api/core/v1"
|
||||
|
||||
type GenericCondition struct {
|
||||
// Type of cluster condition.
|
||||
Type string `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status v1.ConditionStatus `json:"status"`
|
||||
// The last time this condition was updated.
|
||||
LastUpdateTime string `json:"lastUpdateTime,omitempty"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// Human-readable message indicating details about last transition
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
45
vendor/github.com/rancher/wrangler/pkg/kv/split.go
generated
vendored
Normal file
45
vendor/github.com/rancher/wrangler/pkg/kv/split.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package kv
|
||||
|
||||
import "strings"
|
||||
|
||||
// Like split but if there is only one item return "", item
|
||||
func RSplit(s, sep string) (string, string) {
|
||||
parts := strings.SplitN(s, sep, 2)
|
||||
if len(parts) == 1 {
|
||||
return "", strings.TrimSpace(parts[0])
|
||||
}
|
||||
return strings.TrimSpace(parts[0]), strings.TrimSpace(safeIndex(parts, 1))
|
||||
}
|
||||
|
||||
func Split(s, sep string) (string, string) {
|
||||
parts := strings.SplitN(s, sep, 2)
|
||||
return strings.TrimSpace(parts[0]), strings.TrimSpace(safeIndex(parts, 1))
|
||||
}
|
||||
|
||||
func SplitLast(s, sep string) (string, string) {
|
||||
idx := strings.LastIndex(s, sep)
|
||||
if idx > -1 {
|
||||
return strings.TrimSpace(s[:idx]), strings.TrimSpace(s[idx+1:])
|
||||
}
|
||||
return s, ""
|
||||
}
|
||||
|
||||
func SplitMap(s, sep string) map[string]string {
|
||||
return SplitMapFromSlice(strings.Split(s, sep))
|
||||
}
|
||||
|
||||
func SplitMapFromSlice(parts []string) map[string]string {
|
||||
result := map[string]string{}
|
||||
for _, part := range parts {
|
||||
k, v := Split(part, "=")
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func safeIndex(parts []string, idx int) string {
|
||||
if len(parts) <= idx {
|
||||
return ""
|
||||
}
|
||||
return parts[idx]
|
||||
}
|
||||
27
vendor/github.com/rancher/wrangler/pkg/summary/cattletypes.go
generated
vendored
Normal file
27
vendor/github.com/rancher/wrangler/pkg/summary/cattletypes.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"github.com/rancher/wrangler/pkg/data"
|
||||
)
|
||||
|
||||
func checkCattleTypes(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
return checkRelease(obj, condition, summary)
|
||||
}
|
||||
|
||||
func checkRelease(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
if !isKind(obj, "Release", "catalog.cattle.io") {
|
||||
return summary
|
||||
}
|
||||
if obj.String("status", "summary", "state") != "deployed" {
|
||||
return summary
|
||||
}
|
||||
for _, resources := range obj.Slice("spec", "resources") {
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: resources.String("name"),
|
||||
Kind: resources.String("kind"),
|
||||
APIVersion: resources.String("apiVersion"),
|
||||
Type: "manages",
|
||||
})
|
||||
}
|
||||
return summary
|
||||
}
|
||||
45
vendor/github.com/rancher/wrangler/pkg/summary/condition.go
generated
vendored
Normal file
45
vendor/github.com/rancher/wrangler/pkg/summary/condition.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/rancher/wrangler/pkg/data"
|
||||
)
|
||||
|
||||
func getRawConditions(obj data.Object) []data.Object {
|
||||
statusAnn := obj.String("metadata", "annotations", "cattle.io/status")
|
||||
if statusAnn != "" {
|
||||
status := data.Object{}
|
||||
if err := json.Unmarshal([]byte(statusAnn), &status); err == nil {
|
||||
return append(obj.Slice("status", "conditions"), status.Slice("conditions")...)
|
||||
}
|
||||
}
|
||||
return obj.Slice("status", "conditions")
|
||||
}
|
||||
|
||||
func getConditions(obj data.Object) (result []Condition) {
|
||||
for _, condition := range getRawConditions(obj) {
|
||||
result = append(result, Condition{d: condition})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Condition struct {
|
||||
d data.Object
|
||||
}
|
||||
|
||||
func (c Condition) Type() string {
|
||||
return c.d.String("type")
|
||||
}
|
||||
|
||||
func (c Condition) Status() string {
|
||||
return c.d.String("status")
|
||||
}
|
||||
|
||||
func (c Condition) Reason() string {
|
||||
return c.d.String("reason")
|
||||
}
|
||||
|
||||
func (c Condition) Message() string {
|
||||
return c.d.String("message")
|
||||
}
|
||||
153
vendor/github.com/rancher/wrangler/pkg/summary/coretypes.go
generated
vendored
Normal file
153
vendor/github.com/rancher/wrangler/pkg/summary/coretypes.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"github.com/rancher/wrangler/pkg/data"
|
||||
"github.com/rancher/wrangler/pkg/data/convert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func checkPodSelector(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
selector := obj.Map("spec", "selector")
|
||||
if selector == nil {
|
||||
return summary
|
||||
}
|
||||
|
||||
if !isKind(obj, "ReplicaSet", "apps/", "extension/") &&
|
||||
!isKind(obj, "DaemonSet", "apps/", "extension/") &&
|
||||
!isKind(obj, "StatefulSet", "apps/", "extension/") &&
|
||||
!isKind(obj, "Deployment", "apps/", "extension/") &&
|
||||
!isKind(obj, "Job", "batch/") &&
|
||||
!isKind(obj, "Service") {
|
||||
return summary
|
||||
}
|
||||
|
||||
_, hasMatch := selector["matchLabels"]
|
||||
if !hasMatch {
|
||||
_, hasMatch = selector["matchExpressions"]
|
||||
}
|
||||
sel := metav1.LabelSelector{}
|
||||
if hasMatch {
|
||||
if err := convert.ToObj(selector, &sel); err != nil {
|
||||
return summary
|
||||
}
|
||||
} else {
|
||||
sel.MatchLabels = map[string]string{}
|
||||
for k, v := range selector {
|
||||
sel.MatchLabels[k] = convert.ToString(v)
|
||||
}
|
||||
}
|
||||
|
||||
t := "creates"
|
||||
if obj["kind"] == "Service" {
|
||||
t = "selects"
|
||||
}
|
||||
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Kind: "Pod",
|
||||
APIVersion: "v1",
|
||||
Type: t,
|
||||
Selector: &sel,
|
||||
})
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPod(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
if !isKind(obj, "Pod") {
|
||||
return summary
|
||||
}
|
||||
if obj.String("kind") != "Pod" || obj.String("apiVersion") != "v1" {
|
||||
return summary
|
||||
}
|
||||
summary = checkPodConfigMaps(obj, condition, summary)
|
||||
summary = checkPodSecrets(obj, condition, summary)
|
||||
summary = checkPodServiceAccount(obj, condition, summary)
|
||||
summary = checkPodProjectedVolume(obj, condition, summary)
|
||||
summary = checkPodPullSecret(obj, condition, summary)
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPodPullSecret(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
for _, pullSecret := range obj.Slice("imagePullSecrets") {
|
||||
if name := pullSecret.String("name"); name != "" {
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: name,
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
}
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPodProjectedVolume(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
for _, vol := range obj.Slice("spec", "volumes") {
|
||||
for _, source := range vol.Slice("projected", "sources") {
|
||||
if secretName := source.String("secret", "name"); secretName != "" {
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: secretName,
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
}
|
||||
if configMap := source.String("configMap", "name"); configMap != "" {
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: configMap,
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPodConfigMaps(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
names := map[string]bool{}
|
||||
for _, vol := range obj.Slice("spec", "volumes") {
|
||||
name := vol.String("configMap", "name")
|
||||
if name == "" || names[name] {
|
||||
continue
|
||||
}
|
||||
names[name] = true
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: name,
|
||||
Kind: "ConfigMap",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPodSecrets(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
names := map[string]bool{}
|
||||
for _, vol := range obj.Slice("spec", "volumes") {
|
||||
name := vol.String("secret", "secretName")
|
||||
if name == "" || names[name] {
|
||||
continue
|
||||
}
|
||||
names[name] = true
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: name,
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPodServiceAccount(obj data.Object, condition []Condition, summary Summary) Summary {
|
||||
saName := obj.String("spec", "serviceAccountName")
|
||||
summary.Relationships = append(summary.Relationships, Relationship{
|
||||
Name: saName,
|
||||
Kind: "ServiceAccount",
|
||||
APIVersion: "v1",
|
||||
Type: "uses",
|
||||
})
|
||||
return summary
|
||||
|
||||
}
|
||||
98
vendor/github.com/rancher/wrangler/pkg/summary/summarized.go
generated
vendored
Normal file
98
vendor/github.com/rancher/wrangler/pkg/summary/summarized.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type SummarizedObject struct {
|
||||
metav1.PartialObjectMetadata
|
||||
Summary
|
||||
}
|
||||
|
||||
type SummarizedObjectList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []SummarizedObject `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func Summarized(u runtime.Object) *SummarizedObject {
|
||||
if s, ok := u.(*SummarizedObject); ok {
|
||||
return s
|
||||
}
|
||||
|
||||
s := &SummarizedObject{
|
||||
Summary: Summarize(u),
|
||||
}
|
||||
s.APIVersion, s.Kind = u.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind()
|
||||
|
||||
meta, err := meta.Accessor(u)
|
||||
if err == nil {
|
||||
s.Name = meta.GetName()
|
||||
s.Namespace = meta.GetNamespace()
|
||||
s.Generation = meta.GetGeneration()
|
||||
s.UID = meta.GetUID()
|
||||
s.ResourceVersion = meta.GetResourceVersion()
|
||||
s.CreationTimestamp = meta.GetCreationTimestamp()
|
||||
s.DeletionTimestamp = meta.GetDeletionTimestamp()
|
||||
s.Labels = meta.GetLabels()
|
||||
s.Annotations = meta.GetAnnotations()
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (in *SummarizedObjectList) DeepCopyInto(out *SummarizedObjectList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]SummarizedObject, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (in *SummarizedObjectList) DeepCopy() *SummarizedObjectList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SummarizedObjectList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *SummarizedObjectList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (in *SummarizedObject) DeepCopyInto(out *SummarizedObject) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ObjectMeta = *in.ObjectMeta.DeepCopy()
|
||||
out.Summary = *in.Summary.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
func (in *SummarizedObject) DeepCopy() *SummarizedObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SummarizedObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *SummarizedObject) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
425
vendor/github.com/rancher/wrangler/pkg/summary/summarizers.go
generated
vendored
Normal file
425
vendor/github.com/rancher/wrangler/pkg/summary/summarizers.go
generated
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/wrangler/pkg/data"
|
||||
"github.com/rancher/wrangler/pkg/data/convert"
|
||||
"github.com/rancher/wrangler/pkg/kv"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
kstatus "sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||
)
|
||||
|
||||
const (
|
||||
kindSep = ", Kind="
|
||||
)
|
||||
|
||||
var (
|
||||
// True ==
|
||||
// False == error
|
||||
// Unknown == transitioning
|
||||
TransitioningUnknown = map[string]string{
|
||||
"Active": "activating",
|
||||
"AddonDeploy": "provisioning",
|
||||
"AgentDeployed": "provisioning",
|
||||
"BackingNamespaceCreated": "configuring",
|
||||
"Built": "building",
|
||||
"CertsGenerated": "provisioning",
|
||||
"ConfigOK": "configuring",
|
||||
"Created": "creating",
|
||||
"CreatorMadeOwner": "configuring",
|
||||
"DefaultNamespaceAssigned": "configuring",
|
||||
"DefaultNetworkPolicyCreated": "configuring",
|
||||
"DefaultProjectCreated": "configuring",
|
||||
"DockerProvisioned": "provisioning",
|
||||
"Deployed": "deploying",
|
||||
"Drained": "draining",
|
||||
"Downloaded": "downloading",
|
||||
"etcd": "provisioning",
|
||||
"Inactive": "deactivating",
|
||||
"Initialized": "initializing",
|
||||
"Installed": "installing",
|
||||
"NodesCreated": "provisioning",
|
||||
"Pending": "pending",
|
||||
"PodScheduled": "scheduling",
|
||||
"Provisioned": "provisioning",
|
||||
"Refreshed": "refreshed",
|
||||
"Registered": "registering",
|
||||
"Removed": "removing",
|
||||
"Saved": "saving",
|
||||
"Updated": "updating",
|
||||
"Updating": "updating",
|
||||
"Upgraded": "upgrading",
|
||||
"Waiting": "waiting",
|
||||
"InitialRolesPopulated": "activating",
|
||||
"ScalingActive": "pending",
|
||||
"AbleToScale": "pending",
|
||||
"RunCompleted": "running",
|
||||
"Processed": "processed",
|
||||
}
|
||||
|
||||
// True == error
|
||||
// False ==
|
||||
// Unknown ==
|
||||
ErrorTrue = map[string]bool{
|
||||
"OutOfDisk": true,
|
||||
"MemoryPressure": true,
|
||||
"DiskPressure": true,
|
||||
"NetworkUnavailable": true,
|
||||
"KernelHasNoDeadlock": true,
|
||||
"Unschedulable": true,
|
||||
"ReplicaFailure": true,
|
||||
}
|
||||
|
||||
// True ==
|
||||
// False == error
|
||||
// Unknown ==
|
||||
ErrorFalse = map[string]bool{
|
||||
"Failed": true,
|
||||
"Progressing": true,
|
||||
}
|
||||
|
||||
// True ==
|
||||
// False == transitioning
|
||||
// Unknown == error
|
||||
TransitioningFalse = map[string]string{
|
||||
"Completed": "activating",
|
||||
"Ready": "unavailable",
|
||||
"Available": "updating",
|
||||
"Progressing": "inactive",
|
||||
}
|
||||
|
||||
Summarizers []Summarizer
|
||||
)
|
||||
|
||||
type Summarizer func(obj data.Object, conditions []Condition, summary Summary) Summary
|
||||
|
||||
func init() {
|
||||
Summarizers = []Summarizer{
|
||||
checkStatusSummary,
|
||||
checkErrors,
|
||||
checkTransitioning,
|
||||
checkActive,
|
||||
checkPhase,
|
||||
checkInitializing,
|
||||
checkRemoving,
|
||||
checkStandard,
|
||||
checkLoadBalancer,
|
||||
checkPod,
|
||||
checkPodSelector,
|
||||
checkOwner,
|
||||
checkApplyOwned,
|
||||
checkCattleTypes,
|
||||
}
|
||||
}
|
||||
|
||||
func checkOwner(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
ustr := &unstructured.Unstructured{
|
||||
Object: obj,
|
||||
}
|
||||
for _, ownerref := range ustr.GetOwnerReferences() {
|
||||
rel := Relationship{
|
||||
Name: ownerref.Name,
|
||||
Kind: ownerref.Kind,
|
||||
APIVersion: ownerref.APIVersion,
|
||||
Type: "owner",
|
||||
Inbound: true,
|
||||
}
|
||||
if ownerref.Controller != nil && *ownerref.Controller {
|
||||
rel.ControlledBy = true
|
||||
}
|
||||
|
||||
summary.Relationships = append(summary.Relationships, rel)
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkStatusSummary(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
summaryObj := obj.Map("status", "display")
|
||||
if len(summaryObj) == 0 {
|
||||
summaryObj = obj.Map("status", "summary")
|
||||
if len(summaryObj) == 0 {
|
||||
return summary
|
||||
}
|
||||
}
|
||||
obj = summaryObj
|
||||
|
||||
if _, ok := obj["state"]; ok {
|
||||
summary.State = obj.String("state")
|
||||
}
|
||||
if _, ok := obj["transitioning"]; ok {
|
||||
summary.Transitioning = obj.Bool("transitioning")
|
||||
}
|
||||
if _, ok := obj["error"]; ok {
|
||||
summary.Error = obj.Bool("error")
|
||||
}
|
||||
if _, ok := obj["message"]; ok {
|
||||
summary.Message = append(summary.Message, obj.String("message"))
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkStandard(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
if summary.State != "" {
|
||||
return summary
|
||||
}
|
||||
|
||||
// this is a hack to not call the standard summarizers on norman mapped objects
|
||||
if strings.HasPrefix(obj.String("type"), "/") {
|
||||
return summary
|
||||
}
|
||||
|
||||
result, err := kstatus.Compute(&unstructured.Unstructured{Object: obj})
|
||||
if err != nil {
|
||||
return summary
|
||||
}
|
||||
|
||||
switch result.Status {
|
||||
case kstatus.InProgressStatus:
|
||||
summary.State = "in-progress"
|
||||
summary.Message = append(summary.Message, result.Message)
|
||||
summary.Transitioning = true
|
||||
case kstatus.FailedStatus:
|
||||
summary.State = "failed"
|
||||
summary.Message = append(summary.Message, result.Message)
|
||||
summary.Error = true
|
||||
case kstatus.CurrentStatus:
|
||||
summary.State = "active"
|
||||
summary.Message = append(summary.Message, result.Message)
|
||||
case kstatus.TerminatingStatus:
|
||||
summary.State = "removing"
|
||||
summary.Message = append(summary.Message, result.Message)
|
||||
summary.Transitioning = true
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkErrors(_ data.Object, conditions []Condition, summary Summary) Summary {
|
||||
for _, c := range conditions {
|
||||
if (ErrorFalse[c.Type()] && c.Status() == "False") || c.Reason() == "Error" {
|
||||
summary.Error = true
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
if summary.State == "active" || summary.State == "" {
|
||||
summary.State = "error"
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if summary.Error {
|
||||
return summary
|
||||
}
|
||||
|
||||
for _, c := range conditions {
|
||||
if ErrorTrue[c.Type()] && c.Status() == "True" {
|
||||
summary.Error = true
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
}
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkTransitioning(_ data.Object, conditions []Condition, summary Summary) Summary {
|
||||
for _, c := range conditions {
|
||||
newState, ok := TransitioningUnknown[c.Type()]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if c.Status() == "False" {
|
||||
summary.Error = true
|
||||
summary.State = newState
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
} else if c.Status() == "Unknown" && summary.State == "" {
|
||||
summary.Transitioning = true
|
||||
summary.State = newState
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range conditions {
|
||||
if summary.State != "" {
|
||||
break
|
||||
}
|
||||
newState, ok := TransitioningFalse[c.Type()]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if c.Status() == "False" {
|
||||
summary.Transitioning = true
|
||||
summary.State = newState
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
} else if c.Status() == "Unknown" {
|
||||
summary.Error = true
|
||||
summary.State = newState
|
||||
summary.Message = append(summary.Message, c.Message())
|
||||
}
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkActive(obj data.Object, _ []Condition, summary Summary) Summary {
|
||||
if summary.State != "" {
|
||||
return summary
|
||||
}
|
||||
|
||||
switch obj.String("spec", "active") {
|
||||
case "true":
|
||||
summary.State = "active"
|
||||
case "false":
|
||||
summary.State = "inactive"
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkPhase(obj data.Object, _ []Condition, summary Summary) Summary {
|
||||
phase := obj.String("status", "phase")
|
||||
if phase == "Succeeded" {
|
||||
summary.State = "succeeded"
|
||||
summary.Transitioning = false
|
||||
} else if phase != "" && summary.State == "" {
|
||||
summary.State = phase
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkInitializing(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
apiVersion := obj.String("apiVersion")
|
||||
_, hasConditions := obj.Map("status")["conditions"]
|
||||
if summary.State == "" && hasConditions && len(conditions) == 0 && strings.Contains(apiVersion, "cattle.io") {
|
||||
val := obj.String("metadata", "created")
|
||||
if i, err := convert.ToTimestamp(val); err == nil {
|
||||
if time.Unix(i/1000, 0).Add(5 * time.Second).After(time.Now()) {
|
||||
summary.State = "initializing"
|
||||
summary.Transitioning = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkRemoving(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
removed := obj.String("metadata", "removed")
|
||||
if removed == "" {
|
||||
return summary
|
||||
}
|
||||
|
||||
summary.State = "removing"
|
||||
summary.Transitioning = true
|
||||
|
||||
finalizers := obj.StringSlice("metadata", "finalizers")
|
||||
if len(finalizers) == 0 {
|
||||
finalizers = obj.StringSlice("spec", "finalizers")
|
||||
}
|
||||
|
||||
for _, cond := range conditions {
|
||||
if cond.Type() == "Removed" && (cond.Status() == "Unknown" || cond.Status() == "False") && cond.Message() != "" {
|
||||
summary.Message = append(summary.Message, cond.Message())
|
||||
}
|
||||
}
|
||||
|
||||
if len(finalizers) == 0 {
|
||||
return summary
|
||||
}
|
||||
|
||||
_, f := kv.RSplit(finalizers[0], "controller.cattle.io/")
|
||||
if f == "foregroundDeletion" {
|
||||
f = "object cleanup"
|
||||
}
|
||||
|
||||
summary.Message = append(summary.Message, "waiting on "+f)
|
||||
if i, err := convert.ToTimestamp(removed); err == nil {
|
||||
if time.Unix(i/1000, 0).Add(5 * time.Minute).Before(time.Now()) {
|
||||
summary.Error = true
|
||||
}
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func checkLoadBalancer(obj data.Object, _ []Condition, summary Summary) Summary {
|
||||
if (summary.State == "active" || summary.State == "") &&
|
||||
obj.String("kind") == "Service" &&
|
||||
(obj.String("spec", "serviceKind") == "LoadBalancer" ||
|
||||
obj.String("spec", "type") == "LoadBalancer") {
|
||||
addresses := obj.Slice("status", "loadBalancer", "ingress")
|
||||
if len(addresses) == 0 {
|
||||
summary.State = "pending"
|
||||
summary.Transitioning = true
|
||||
summary.Message = append(summary.Message, "Load balancer is being provisioned")
|
||||
}
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func isKind(obj data.Object, kind string, apiGroups ...string) bool {
|
||||
if obj.String("kind") != kind {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(apiGroups) == 0 {
|
||||
return obj.String("apiVersion") == "v1"
|
||||
}
|
||||
|
||||
if len(apiGroups) == 0 {
|
||||
apiGroups = []string{""}
|
||||
}
|
||||
|
||||
for _, group := range apiGroups {
|
||||
switch {
|
||||
case group == "":
|
||||
if obj.String("apiVersion") == "v1" {
|
||||
return true
|
||||
}
|
||||
case group[len(group)-1] == '/':
|
||||
if strings.HasPrefix(obj.String("apiVersion"), group) {
|
||||
return true
|
||||
}
|
||||
default:
|
||||
if obj.String("apiVersion") != group {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func checkApplyOwned(obj data.Object, conditions []Condition, summary Summary) Summary {
|
||||
if len(obj.Slice("metadata", "ownerReferences")) > 0 {
|
||||
return summary
|
||||
}
|
||||
|
||||
annotations := obj.Map("metadata", "annotations")
|
||||
gvkString := convert.ToString(annotations["objectset.rio.cattle.io/owner-gvk"])
|
||||
i := strings.Index(gvkString, kindSep)
|
||||
if i <= 0 {
|
||||
return summary
|
||||
}
|
||||
|
||||
name := convert.ToString(annotations["objectset.rio.cattle.io/owner-name"])
|
||||
namespace := convert.ToString(annotations["objectset.rio.cattle.io/owner-namespace"])
|
||||
|
||||
apiVersion := gvkString[:i]
|
||||
kind := gvkString[i+len(kindSep):]
|
||||
|
||||
rel := Relationship{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Kind: kind,
|
||||
APIVersion: apiVersion,
|
||||
Type: "applies",
|
||||
Inbound: true,
|
||||
}
|
||||
|
||||
summary.Relationships = append(summary.Relationships, rel)
|
||||
|
||||
return summary
|
||||
}
|
||||
123
vendor/github.com/rancher/wrangler/pkg/summary/summary.go
generated
vendored
Normal file
123
vendor/github.com/rancher/wrangler/pkg/summary/summary.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/wrangler/pkg/data"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type Summary struct {
|
||||
State string
|
||||
Error bool
|
||||
Transitioning bool
|
||||
Message []string
|
||||
Attributes map[string]interface{}
|
||||
Relationships []Relationship
|
||||
}
|
||||
|
||||
type Relationship struct {
|
||||
Name string
|
||||
Namespace string
|
||||
ControlledBy bool
|
||||
Kind string
|
||||
APIVersion string
|
||||
Inbound bool
|
||||
Type string
|
||||
Selector *metav1.LabelSelector
|
||||
}
|
||||
|
||||
func (s Summary) String() string {
|
||||
if !s.Transitioning && !s.Error {
|
||||
return s.State
|
||||
}
|
||||
var msg string
|
||||
if s.Transitioning {
|
||||
msg = "[progressing"
|
||||
}
|
||||
if s.Error {
|
||||
if len(msg) > 0 {
|
||||
msg += ",error]"
|
||||
} else {
|
||||
msg = "error]"
|
||||
}
|
||||
} else {
|
||||
msg += "]"
|
||||
}
|
||||
if len(s.Message) > 0 {
|
||||
msg = msg + " " + s.Message[0]
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func (s Summary) IsReady() bool {
|
||||
return !s.Error && !s.Transitioning
|
||||
}
|
||||
|
||||
func (s *Summary) DeepCopy() *Summary {
|
||||
v := *s
|
||||
return &v
|
||||
}
|
||||
|
||||
func (s *Summary) DeepCopyInto(v *Summary) {
|
||||
*v = *s
|
||||
}
|
||||
|
||||
func dedupMessage(messages []string) []string {
|
||||
if len(messages) <= 1 {
|
||||
return messages
|
||||
}
|
||||
|
||||
seen := map[string]bool{}
|
||||
var result []string
|
||||
|
||||
for _, message := range messages {
|
||||
message = strings.TrimSpace(message)
|
||||
if message == "" {
|
||||
continue
|
||||
}
|
||||
if seen[message] {
|
||||
continue
|
||||
}
|
||||
seen[message] = true
|
||||
result = append(result, message)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Summarize(runtimeObj runtime.Object) Summary {
|
||||
var (
|
||||
obj data.Object
|
||||
summary Summary
|
||||
)
|
||||
|
||||
if s, ok := runtimeObj.(*SummarizedObject); ok {
|
||||
return s.Summary
|
||||
}
|
||||
|
||||
unstr, ok := runtimeObj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return summary
|
||||
}
|
||||
|
||||
if unstr != nil {
|
||||
obj = unstr.Object
|
||||
}
|
||||
|
||||
conditions := getConditions(obj)
|
||||
|
||||
for _, summarizer := range Summarizers {
|
||||
summary = summarizer(obj, conditions, summary)
|
||||
}
|
||||
|
||||
if summary.State == "" {
|
||||
summary.State = "active"
|
||||
}
|
||||
|
||||
summary.State = strings.ToLower(summary.State)
|
||||
summary.Message = dedupMessage(summary.Message)
|
||||
return summary
|
||||
}
|
||||
Reference in New Issue
Block a user