k3s/vendor/github.com/rancher/wrangler/pkg/condition/condition.go

259 lines
5.7 KiB
Go
Raw Normal View History

2019-01-31 22:42:07 +00:00
package condition
import (
"reflect"
"time"
2020-04-22 22:34:19 +00:00
"github.com/rancher/wrangler/pkg/generic"
2020-03-26 21:07:15 +00:00
"github.com/sirupsen/logrus"
2019-01-31 22:42:07 +00:00
)
type Cond string
2020-03-26 21:07:15 +00:00
func (c Cond) GetStatus(obj interface{}) string {
2019-05-09 22:03:45 +00:00
return getStatus(obj, string(c))
}
2019-01-31 22:42:07 +00:00
2020-03-26 21:07:15 +00:00
func (c Cond) SetError(obj interface{}, reason string, err error) {
2020-04-22 22:34:19 +00:00
if err == nil || err == generic.ErrSkip {
2019-05-09 22:03:45 +00:00
c.True(obj)
c.Message(obj, "")
c.Reason(obj, reason)
return
}
if reason == "" {
reason = "Error"
}
c.False(obj)
c.Message(obj, err.Error())
c.Reason(obj, reason)
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) MatchesError(obj interface{}, reason string, err error) bool {
2019-05-09 22:03:45 +00:00
if err == nil {
return c.IsTrue(obj) &&
c.GetMessage(obj) == "" &&
c.GetReason(obj) == reason
}
if reason == "" {
reason = "Error"
}
return c.IsFalse(obj) &&
c.GetMessage(obj) == err.Error() &&
c.GetReason(obj) == reason
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) SetStatus(obj interface{}, status string) {
2019-05-09 22:03:45 +00:00
setStatus(obj, string(c), status)
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) SetStatusBool(obj interface{}, val bool) {
2019-05-09 22:03:45 +00:00
if val {
setStatus(obj, string(c), "True")
} else {
setStatus(obj, string(c), "False")
}
}
2020-03-26 21:07:15 +00:00
func (c Cond) True(obj interface{}) {
2019-05-09 22:03:45 +00:00
setStatus(obj, string(c), "True")
}
2020-03-26 21:07:15 +00:00
func (c Cond) IsTrue(obj interface{}) bool {
2019-05-09 22:03:45 +00:00
return getStatus(obj, string(c)) == "True"
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) False(obj interface{}) {
2019-01-31 22:42:07 +00:00
setStatus(obj, string(c), "False")
}
2020-03-26 21:07:15 +00:00
func (c Cond) IsFalse(obj interface{}) bool {
2019-01-31 22:42:07 +00:00
return getStatus(obj, string(c)) == "False"
}
2020-03-26 21:07:15 +00:00
func (c Cond) Unknown(obj interface{}) {
2019-05-09 22:03:45 +00:00
setStatus(obj, string(c), "Unknown")
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) IsUnknown(obj interface{}) bool {
2019-05-09 22:03:45 +00:00
return getStatus(obj, string(c)) == "Unknown"
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) LastUpdated(obj interface{}, ts string) {
2019-05-09 22:03:45 +00:00
setTS(obj, string(c), ts)
}
2020-03-26 21:07:15 +00:00
func (c Cond) GetLastUpdated(obj interface{}) string {
2019-05-09 22:03:45 +00:00
return getTS(obj, string(c))
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func (c Cond) CreateUnknownIfNotExists(obj interface{}) {
2019-01-31 22:42:07 +00:00
condSlice := getValue(obj, "Status", "Conditions")
2020-03-26 21:07:15 +00:00
cond := findCond(obj, condSlice, string(c))
2019-01-31 22:42:07 +00:00
if cond == nil {
c.Unknown(obj)
}
}
2020-03-26 21:07:15 +00:00
func (c Cond) Reason(obj interface{}, reason string) {
2019-01-31 22:42:07 +00:00
cond := findOrCreateCond(obj, string(c))
getFieldValue(cond, "Reason").SetString(reason)
}
2020-03-26 21:07:15 +00:00
func (c Cond) GetReason(obj interface{}) string {
2019-05-09 22:03:45 +00:00
cond := findOrNotCreateCond(obj, string(c))
if cond == nil {
return ""
}
return getFieldValue(*cond, "Reason").String()
}
2020-03-26 21:07:15 +00:00
func (c Cond) SetMessageIfBlank(obj interface{}, message string) {
2019-01-31 22:42:07 +00:00
if c.GetMessage(obj) == "" {
c.Message(obj, message)
}
}
2020-03-26 21:07:15 +00:00
func (c Cond) Message(obj interface{}, message string) {
2019-01-31 22:42:07 +00:00
cond := findOrCreateCond(obj, string(c))
setValue(cond, "Message", message)
}
2020-03-26 21:07:15 +00:00
func (c Cond) GetMessage(obj interface{}) string {
2019-01-31 22:42:07 +00:00
cond := findOrNotCreateCond(obj, string(c))
if cond == nil {
return ""
}
return getFieldValue(*cond, "Message").String()
}
func touchTS(value reflect.Value) {
now := time.Now().Format(time.RFC3339)
getFieldValue(value, "LastUpdateTime").SetString(now)
}
func getStatus(obj interface{}, condName string) string {
cond := findOrNotCreateCond(obj, condName)
if cond == nil {
return ""
}
return getFieldValue(*cond, "Status").String()
}
func setTS(obj interface{}, condName, ts string) {
cond := findOrCreateCond(obj, condName)
getFieldValue(cond, "LastUpdateTime").SetString(ts)
}
func getTS(obj interface{}, condName string) string {
cond := findOrNotCreateCond(obj, condName)
if cond == nil {
return ""
}
return getFieldValue(*cond, "LastUpdateTime").String()
}
func setStatus(obj interface{}, condName, status string) {
2020-04-22 22:34:19 +00:00
if reflect.TypeOf(obj).Kind() != reflect.Ptr {
panic("obj passed must be a pointer")
}
2019-01-31 22:42:07 +00:00
cond := findOrCreateCond(obj, condName)
setValue(cond, "Status", status)
}
func setValue(cond reflect.Value, fieldName, newValue string) {
value := getFieldValue(cond, fieldName)
if value.String() != newValue {
value.SetString(newValue)
touchTS(cond)
}
}
func findOrNotCreateCond(obj interface{}, condName string) *reflect.Value {
condSlice := getValue(obj, "Status", "Conditions")
2020-04-22 22:34:19 +00:00
if !condSlice.IsValid() {
condSlice = getValue(obj, "Conditions")
}
2020-03-26 21:07:15 +00:00
return findCond(obj, condSlice, condName)
2019-01-31 22:42:07 +00:00
}
func findOrCreateCond(obj interface{}, condName string) reflect.Value {
condSlice := getValue(obj, "Status", "Conditions")
2020-03-26 21:07:15 +00:00
if !condSlice.IsValid() {
condSlice = getValue(obj, "Conditions")
}
cond := findCond(obj, condSlice, condName)
2019-01-31 22:42:07 +00:00
if cond != nil {
return *cond
}
newCond := reflect.New(condSlice.Type().Elem()).Elem()
newCond.FieldByName("Type").SetString(condName)
newCond.FieldByName("Status").SetString("Unknown")
condSlice.Set(reflect.Append(condSlice, newCond))
2020-03-26 21:07:15 +00:00
return *findCond(obj, condSlice, condName)
2019-01-31 22:42:07 +00:00
}
2020-03-26 21:07:15 +00:00
func findCond(obj interface{}, val reflect.Value, name string) *reflect.Value {
defer func() {
if recover() != nil {
logrus.Fatalf("failed to find .Status.Conditions field on %v", reflect.TypeOf(obj))
}
}()
2019-01-31 22:42:07 +00:00
for i := 0; i < val.Len(); i++ {
cond := val.Index(i)
typeVal := getFieldValue(cond, "Type")
if typeVal.String() == name {
return &cond
}
}
return nil
}
func getValue(obj interface{}, name ...string) reflect.Value {
if obj == nil {
return reflect.Value{}
}
v := reflect.ValueOf(obj)
t := v.Type()
if t.Kind() == reflect.Ptr {
v = v.Elem()
t = v.Type()
}
field := v.FieldByName(name[0])
if len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func getFieldValue(v reflect.Value, name ...string) reflect.Value {
2020-04-22 22:34:19 +00:00
if !v.IsValid() {
return v
}
2019-01-31 22:42:07 +00:00
field := v.FieldByName(name[0])
if len(name) == 1 {
return field
}
return getFieldValue(field, name[1:]...)
}
func Error(reason string, err error) error {
return &conditionError{
reason: reason,
message: err.Error(),
}
}
type conditionError struct {
reason string
message string
}
func (e *conditionError) Error() string {
return e.message
}