Adopt k8s standardized conditions
Use the newly introduced standardized Condition type kubernetes/enhancements#1624 Relates to fluxcd/flux2#225 Signed-off-by: Aurel Canciu <aurelcanciu@gmail.com>
This commit is contained in:
parent
453ab90ab6
commit
ba7800eaf6
|
|
@ -16,55 +16,7 @@ limitations under the License.
|
|||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Condition contains condition information for a toolkit resource.
|
||||
type Condition struct {
|
||||
// Type of the condition, currently ('Ready').
|
||||
// +required
|
||||
Type string `json:"type"`
|
||||
|
||||
// Status of the condition, one of ('True', 'False', 'Unknown').
|
||||
// +required
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
|
||||
// LastTransitionTime is the timestamp corresponding to the last status
|
||||
// change of this condition.
|
||||
// +required
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
|
||||
// Reason is a brief machine readable explanation for the condition's last
|
||||
// transition.
|
||||
// +required
|
||||
Reason string `json:"reason,omitempty"`
|
||||
|
||||
// Message is a human readable description of the details of the last
|
||||
// transition, complementing reason.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// ReadyCondition records the last reconciliation result.
|
||||
ReadyCondition string = "Ready"
|
||||
)
|
||||
|
||||
const (
|
||||
// ReconciliationSucceededReason represents the fact that the reconciliation of the resource has succeeded.
|
||||
ReconciliationSucceededReason string = "ReconciliationSucceeded"
|
||||
|
||||
// ReconciliationFailedReason represents the fact that the reconciliation of the resource has failed.
|
||||
ReconciliationFailedReason string = "ReconciliationFailed"
|
||||
|
||||
// ImageURLInvalidReason represents the fact that a given repository has an invalid image URL.
|
||||
ImageURLInvalidReason string = "ImageURLInvalid"
|
||||
|
||||
// ProgressingReason represents the fact that a reconciliation is underway.
|
||||
ProgressingReason string = "Progressing"
|
||||
|
||||
// SuspendedReason represents the fact that the reconciliation is suspended.
|
||||
SuspendedReason string = "Suspended"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ type ScanResult struct {
|
|||
// ImageRepositoryStatus defines the observed state of ImageRepository
|
||||
type ImageRepositoryStatus struct {
|
||||
// +optional
|
||||
Conditions []Condition `json:"conditions,omitempty"`
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
|
||||
// ObservedGeneration is the last reconciled generation.
|
||||
// +optional
|
||||
|
|
@ -75,10 +75,10 @@ type ImageRepositoryStatus struct {
|
|||
}
|
||||
|
||||
// SetImageRepositoryReadiness sets the ready condition with the given status, reason and message.
|
||||
func SetImageRepositoryReadiness(ir ImageRepository, status corev1.ConditionStatus, reason, message string) ImageRepository {
|
||||
ir.Status.Conditions = []Condition{
|
||||
func SetImageRepositoryReadiness(ir ImageRepository, status metav1.ConditionStatus, reason, message string) ImageRepository {
|
||||
ir.Status.Conditions = []metav1.Condition{
|
||||
{
|
||||
Type: ReadyCondition,
|
||||
Type: meta.ReadyCondition,
|
||||
Status: status,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: reason,
|
||||
|
|
@ -91,7 +91,7 @@ func SetImageRepositoryReadiness(ir ImageRepository, status corev1.ConditionStat
|
|||
|
||||
func GetLastTransitionTime(ir ImageRepository) *metav1.Time {
|
||||
for _, condition := range ir.Status.Conditions {
|
||||
if condition.Type == ReadyCondition {
|
||||
if condition.Type == meta.ReadyCondition {
|
||||
return &condition.LastTransitionTime
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,22 +26,6 @@ import (
|
|||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Condition) DeepCopyInto(out *Condition) {
|
||||
*out = *in
|
||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
|
||||
func (in *Condition) DeepCopy() *Condition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Condition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImagePolicy) DeepCopyInto(out *ImagePolicy) {
|
||||
*out = *in
|
||||
|
|
@ -242,7 +226,7 @@ func (in *ImageRepositoryStatus) DeepCopyInto(out *ImageRepositoryStatus) {
|
|||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,30 +77,69 @@ spec:
|
|||
type: string
|
||||
conditions:
|
||||
items:
|
||||
description: Condition contains condition information for a toolkit
|
||||
resource.
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are:
|
||||
\"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type
|
||||
\ // +patchStrategy=merge // +listType=map // +listMapKey=type
|
||||
\ Conditions []metav1.Condition `json:\"conditions,omitempty\"
|
||||
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`
|
||||
\n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the timestamp corresponding
|
||||
to the last status change of this condition.
|
||||
description: lastTransitionTime is the 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.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: Message is a human readable description of the
|
||||
details of the last transition, complementing reason.
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: Reason is a brief machine readable explanation
|
||||
for the condition's last transition.
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of ('True', 'False',
|
||||
'Unknown').
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: Type of the condition, currently ('Ready').
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
kuberecorder "k8s.io/client-go/tools/record"
|
||||
|
|
@ -87,8 +88,8 @@ func (r *ImageRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, er
|
|||
msg := "ImageRepository is suspended, skipping reconciliation"
|
||||
status := imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionFalse,
|
||||
imagev1alpha1.SuspendedReason,
|
||||
metav1.ConditionFalse,
|
||||
meta.SuspendedReason,
|
||||
msg,
|
||||
)
|
||||
if err := r.Status().Update(ctx, &status); err != nil {
|
||||
|
|
@ -103,7 +104,7 @@ func (r *ImageRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, er
|
|||
if err != nil {
|
||||
status := imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionFalse,
|
||||
metav1.ConditionFalse,
|
||||
imagev1alpha1.ImageURLInvalidReason,
|
||||
err.Error(),
|
||||
)
|
||||
|
|
@ -152,8 +153,8 @@ func (r *ImageRepositoryReconciler) scan(ctx context.Context, imageRepo imagev1a
|
|||
}, &secret); err != nil {
|
||||
return imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionFalse,
|
||||
imagev1alpha1.ReconciliationFailedReason,
|
||||
metav1.ConditionFalse,
|
||||
meta.ReconciliationFailedReason,
|
||||
err.Error(),
|
||||
), err
|
||||
}
|
||||
|
|
@ -161,8 +162,8 @@ func (r *ImageRepositoryReconciler) scan(ctx context.Context, imageRepo imagev1a
|
|||
if err != nil {
|
||||
return imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionFalse,
|
||||
imagev1alpha1.ReconciliationFailedReason,
|
||||
metav1.ConditionFalse,
|
||||
meta.ReconciliationFailedReason,
|
||||
err.Error(),
|
||||
), err
|
||||
}
|
||||
|
|
@ -173,8 +174,8 @@ func (r *ImageRepositoryReconciler) scan(ctx context.Context, imageRepo imagev1a
|
|||
if err != nil {
|
||||
return imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionFalse,
|
||||
imagev1alpha1.ReconciliationFailedReason,
|
||||
metav1.ConditionFalse,
|
||||
meta.ReconciliationFailedReason,
|
||||
err.Error(),
|
||||
), err
|
||||
}
|
||||
|
|
@ -193,8 +194,8 @@ func (r *ImageRepositoryReconciler) scan(ctx context.Context, imageRepo imagev1a
|
|||
|
||||
return imagev1alpha1.SetImageRepositoryReadiness(
|
||||
imageRepo,
|
||||
corev1.ConditionTrue,
|
||||
imagev1alpha1.ReconciliationSucceededReason,
|
||||
metav1.ConditionTrue,
|
||||
meta.ReconciliationSucceededReason,
|
||||
fmt.Sprintf("successful scan, found %v tags", len(tags)),
|
||||
), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ var _ = Describe("ImageRepository controller", func() {
|
|||
Expect(cond.Message).To(
|
||||
Equal("ImageRepository is suspended, skipping reconciliation"))
|
||||
Expect(cond.Reason).To(
|
||||
Equal(imagev1alpha1.SuspendedReason))
|
||||
Equal(meta.SuspendedReason))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue