1
0
mirror of https://github.com/rancher/types.git synced 2025-06-27 14:06:49 +00:00
types/status/status.go
Craig Jellick e5890bff08 Cluster conditions
For creating a default project and assigning the default namespace to it
2018-01-08 19:29:43 +00:00

179 lines
4.6 KiB
Go

package status
import (
"strings"
"time"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/values"
)
type conditionMapping struct {
Name string
State string
Transition bool
Error bool
FalseIsGood bool
}
type condition struct {
Type string
Status string
Message string
}
var conditionMappings = []conditionMapping{
{Name: "Initialized", Transition: true, State: "initializing"},
{Name: "Available", Transition: true, State: "activating"},
{Name: "Progressing", Transition: true, State: "updating"},
{Name: "Provisioned", Transition: true, State: "provisioning"},
{Name: "Saved", Transition: true, State: "saving"},
{Name: "AgentInstalled", Transition: true, State: "installing"},
{Name: "Updating", Transition: true, FalseIsGood: true, State: "updating"},
{Name: "ConfigOK", Transition: true, State: "configuring"},
{Name: "PodScheduled", Transition: true, State: "scheduling"},
{Name: "Completed", State: "completed"},
{Name: "Failed", Error: true, State: "error"},
{Name: "OutOfDisk", Error: true, FalseIsGood: true},
{Name: "MemoryPressure", Error: true, FalseIsGood: true},
{Name: "DiskPressure", Error: true, FalseIsGood: true},
{Name: "NetworkUnavailable", Error: true, FalseIsGood: true},
{Name: "KernelHasNoDeadlock", Error: true, FalseIsGood: true},
{Name: "Unschedulable", Error: true, FalseIsGood: true},
{Name: "ReplicaFailure", Error: true, FalseIsGood: true},
{Name: "Ready", Transition: false, State: "activating"},
{Name: "BackingNamespaceCreated", Transition: true, State: "activating"},
{Name: "CreatorMadeOwner", Transition: true, State: "activating"},
{Name: "DefaultProjectCreated", Transition: true, State: "activating"},
{Name: "DefaultNamespaceAssigned", Transition: true, State: "activating"},
}
func Set(data map[string]interface{}) {
if data == nil {
return
}
val, ok := values.GetValue(data, "metadata", "removed")
if ok && val != "" && val != nil {
data["state"] = "removing"
data["transitioning"] = "yes"
finalizers, ok := values.GetStringSlice(data, "metadata", "finalizers")
if ok && len(finalizers) > 0 {
data["transitioningMessage"] = "Waiting on " + finalizers[0]
if i, err := convert.ToTimestamp(val); err == nil {
if time.Unix(i/1000, 0).Add(5 * time.Minute).Before(time.Now()) {
data["transitioning"] = "error"
}
}
}
return
}
val, ok = values.GetValue(data, "status", "conditions")
var conditions []condition
if err := convert.ToObj(val, &conditions); err != nil {
// ignore error
return
}
conditionMap := map[string]condition{}
for _, c := range conditions {
conditionMap[c.Type] = condition{
Status: c.Status,
Message: c.Message,
}
}
state := ""
error := false
transitioning := false
message := ""
for _, conditionMapping := range conditionMappings {
good := true
condition, ok := conditionMap[conditionMapping.Name]
if !ok {
continue
}
if conditionMapping.FalseIsGood && condition.Status == "True" {
good = false
} else if !conditionMapping.FalseIsGood && condition.Status == "False" {
good = false
} else if conditionMapping.Transition && !conditionMapping.FalseIsGood && condition.Status == "Unknown" {
good = false
}
if !good && conditionMapping.Transition {
transitioning = true
if len(message) > 0 {
message = strings.Join([]string{message, condition.Message}, ",")
} else {
message = condition.Message
}
}
if !good && state == "" && conditionMapping.State != "" {
state = conditionMapping.State
}
if !good && conditionMapping.Error {
error = true
if len(message) > 0 {
message = strings.Join([]string{message, condition.Message}, ",")
} else {
message = condition.Message
}
}
}
if state == "" {
val, ok := values.GetValue(data, "spec", "active")
if ok {
if convert.ToBool(val) {
state = "active"
} else {
state = "inactive"
}
}
}
if state == "" {
val, _ := values.GetValueN(data, "status", "phase").(string)
if val != "" {
state = val
}
}
if state == "" && len(conditions) == 0 {
if val, ok := values.GetValue(data, "metadata", "created"); ok {
if i, err := convert.ToTimestamp(val); err == nil {
if time.Unix(i/1000, 0).Add(5 * time.Second).Before(time.Now()) {
state = "active"
} else {
state = "initializing"
transitioning = true
}
}
}
}
if state == "" {
state = "active"
}
data["state"] = strings.ToLower(state)
if error {
data["transitioning"] = "error"
} else if transitioning {
data["transitioning"] = "yes"
} else {
data["transitioning"] = "no"
}
data["transitioningMessage"] = message
}