Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move meta conditions utils to conditions package #539

Merged
merged 1 commit into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 55 additions & 143 deletions api/v1/conditions.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright AppsCode Inc. and Contributors
Copyright 2023.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -17,160 +17,72 @@ limitations under the License.
package v1

import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// KEP: https://github.com/kubernetes/enhancements/blob/ced773ab59f0ff080888a912ab99474245623dad/keps/sig-api-machinery/1623-standardize-conditions/README.md
// ConditionSeverity expresses the severity of a Condition Type failing.
type ConditionSeverity string

// List of common condition types
const (
ConditionProgressing = "Progressing"
ConditionInitialized = "Initialized"
ConditionReady = "Ready"
ConditionAvailable = "Available"
ConditionFailed = "Failed"

ConditionRequestApproved = "Approved"
ConditionRequestDenied = "Denied"
)

func NewCondition(reason string, message string, generation int64, conditionStatus ...bool) metav1.Condition {
cs := metav1.ConditionTrue
if len(conditionStatus) > 0 && !conditionStatus[0] {
cs = metav1.ConditionFalse
}

return metav1.Condition{
Type: reason,
Reason: reason,
Message: message,
Status: cs,
LastTransitionTime: metav1.Now(),
ObservedGeneration: generation,
}
}

// HasCondition returns "true" if the desired condition provided in "condType" is present in the condition list.
// Otherwise, it returns "false".
func HasCondition(conditions []metav1.Condition, condType string) bool {
for i := range conditions {
if conditions[i].Type == condType {
return true
}
}
return false
}

// GetCondition returns a pointer to the desired condition referred by "condType". Otherwise, it returns nil.
func GetCondition(conditions []metav1.Condition, condType string) (int, *metav1.Condition) {
for i := range conditions {
c := conditions[i]
if c.Type == condType {
return i, &c
}
}
return -1, nil
}

// SetCondition add/update the desired condition to the condition list. It does nothing if the condition is already in
// its desired state.
func SetCondition(conditions []metav1.Condition, newCondition metav1.Condition) []metav1.Condition {
idx, curCond := GetCondition(conditions, newCondition.Type)
// If the current condition is in its desired state, we have nothing to do. Just return the original condition list.
if curCond != nil &&
curCond.Status == newCondition.Status &&
curCond.Reason == newCondition.Reason &&
curCond.Message == newCondition.Message &&
curCond.ObservedGeneration == newCondition.ObservedGeneration {
return conditions
}
// The desired conditions is not in the condition list or is not in its desired state.
// Update it if present in the condition list, or append the new condition if it does not present.
newCondition.LastTransitionTime = metav1.Now()
if idx == -1 {
conditions = append(conditions, newCondition)
} else if newCondition.ObservedGeneration >= curCond.ObservedGeneration {
// only update if the new condition is based on observed generation at least as updated as the current condition
conditions[idx] = newCondition
}
return conditions
}
// ConditionSeverityError specifies that a condition with `Status=False` is an error.
ConditionSeverityError ConditionSeverity = "Error"

// RemoveCondition remove a condition from the condition list referred by "condType" parameter.
func RemoveCondition(conditions []metav1.Condition, condType string) []metav1.Condition {
idx, _ := GetCondition(conditions, condType)
if idx == -1 {
// The desired condition is not present in the condition list. So, nothing to do.
return conditions
}
return append(conditions[:idx], conditions[idx+1:]...)
}
// ConditionSeverityWarning specifies that a condition with `Status=False` is a warning.
ConditionSeverityWarning ConditionSeverity = "Warning"

// IsConditionTrue returns "true" if the desired condition is in true state.
// It returns "false" if the desired condition is not in "true" state or is not in the condition list.
func IsConditionTrue(conditions []metav1.Condition, condType string) bool {
for i := range conditions {
if conditions[i].Type == condType && conditions[i].Status == metav1.ConditionTrue {
return true
}
}
return false
}

// IsConditionFalse returns "true" if the desired condition is in false state.
// It returns "false" if the desired condition is not in "false" state or is not in the condition list.
func IsConditionFalse(conditions []metav1.Condition, condType string) bool {
for i := range conditions {
if conditions[i].Type == condType && conditions[i].Status == metav1.ConditionFalse {
return true
}
}
return false
}
// ConditionSeverityInfo specifies that a condition with `Status=False` is informative.
ConditionSeverityInfo ConditionSeverity = "Info"

// IsConditionUnknown returns "true" if the desired condition is in unknown state.
// It returns "false" if the desired condition is not in "unknown" state or is not in the condition list.
func IsConditionUnknown(conditions []metav1.Condition, condType string) bool {
for i := range conditions {
if conditions[i].Type == condType && conditions[i].Status == metav1.ConditionUnknown {
return true
}
}
return false
}
// ConditionSeverityNone should apply only to util with `Status=True`.
ConditionSeverityNone ConditionSeverity = ""
)

// Status defines the set of statuses a resource can have.
// Based on kstatus: https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus
// +kubebuilder:validation:Enum=InProgress;Failed;Current;Terminating;NotFound;Unknown
type Status string
// ConditionType is a valid value for Condition.Type.
type ConditionType string

const (
// The set of status conditions which can be assigned to resources.
InProgressStatus Status = "InProgress"
FailedStatus Status = "Failed"
CurrentStatus Status = "Current"
TerminatingStatus Status = "Terminating"
NotFoundStatus Status = "NotFound"
UnknownStatus Status = "Unknown"
// ReadyCondition defines the Ready condition type that summarizes the operational state of an object.
ReadyCondition ConditionType = "Ready"
)

var Statuses = []Status{InProgressStatus, FailedStatus, CurrentStatus, TerminatingStatus, UnknownStatus}

// String returns the status as a string.
func (s Status) String() string {
return string(s)
// Condition defines an observation of a object operational state.
type Condition struct {
// Type of condition in CamelCase or in foo.example.com/CamelCase.
// Many .condition.type values are consistent across resources like Available, but because arbitrary util
// can be useful (see .node.status.util), the ability to deconflict is important.
Type ConditionType `json:"type" protobuf:"bytes,4,opt,name=type,casttype=ConditionType"`

// Status of the condition, one of True, False, Unknown.
Status metav1.ConditionStatus `json:"status" protobuf:"bytes,5,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`

// If set, this represents the .metadata.generation that the condition was set based upon.
// For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date
// with respect to the current state of the instance.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`

// Severity provides an explicit classification of Reason code, so the users or machines can immediately
// understand the current situation and act accordingly.
// The Severity field MUST be set only when Status=False.
// +optional
Severity ConditionSeverity `json:"severity,omitempty" protobuf:"bytes,6,opt,name=severity,casttype=ConditionSeverity"`

// Last time the condition transitioned from one status to another.
// This should be when the underlying condition changed. If that is not known, then using the time when
// the API field changed is acceptable.
LastTransitionTime metav1.Time `json:"lastTransitionTime" protobuf:"bytes,7,opt,name=lastTransitionTime"`

// The reason for the condition's last transition in CamelCase.
// The specific API may choose whether this field is considered a guaranteed API.
// This field may not be empty.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,8,opt,name=reason"`

// A human-readable message indicating details about the transition.
// This field may be empty.
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,9,opt,name=message"`
}

// StatusFromStringOrDie turns a string into a Status. Will panic if the provided string is
// not a valid status.
func StatusFromStringOrDie(text string) Status {
s := Status(text)
for _, r := range Statuses {
if s == r {
return s
}
}
panic(fmt.Errorf("string has invalid status: %s", s))
}
// Conditions provide observations of the operational state of a object.
type Conditions []Condition
88 changes: 0 additions & 88 deletions api/v1/types.go

This file was deleted.

Loading
Loading