@@ -12,17 +12,18 @@ import (
1212
1313 appsv1 "k8s.io/api/apps/v1"
1414 corev1 "k8s.io/api/core/v1"
15+ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
1516 "k8s.io/apimachinery/pkg/api/equality"
1617 "k8s.io/apimachinery/pkg/api/meta"
1718 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1819 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
19- "k8s.io/apimachinery/pkg/runtime"
2020 "k8s.io/apimachinery/pkg/runtime/schema"
2121 "k8s.io/apimachinery/pkg/types"
2222 "k8s.io/apimachinery/pkg/util/sets"
2323 "pkg.package-operator.run/boxcutter"
2424 "pkg.package-operator.run/boxcutter/machinery"
2525 machinerytypes "pkg.package-operator.run/boxcutter/machinery/types"
26+ "pkg.package-operator.run/boxcutter/probing"
2627 ctrl "sigs.k8s.io/controller-runtime"
2728 "sigs.k8s.io/controller-runtime/pkg/builder"
2829 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -430,31 +431,9 @@ func toBoxcutterRevision(rev *ocv1.ClusterExtensionRevision) (*boxcutter.Revisio
430431
431432 opts := []boxcutter.RevisionReconcileOption {
432433 boxcutter .WithPreviousOwners (previous ),
433- boxcutter .WithProbe (boxcutter .ProgressProbeType , boxcutter .ProbeFunc (func (obj client.Object ) (bool , []string ) {
434- deployGK := schema.GroupKind {
435- Group : "apps" , Kind : "Deployment" ,
436- }
437- if obj .GetObjectKind ().GroupVersionKind ().GroupKind () != deployGK {
438- return true , nil
439- }
440- ustrObj := obj .(* unstructured.Unstructured )
441- depl := & appsv1.Deployment {}
442- if err := runtime .DefaultUnstructuredConverter .FromUnstructured (ustrObj .Object , depl ); err != nil {
443- return false , []string {err .Error ()}
444- }
445-
446- if depl .Status .ObservedGeneration != depl .Generation {
447- return false , []string {".status.observedGeneration outdated" }
448- }
449- for _ , cond := range depl .Status .Conditions {
450- if cond .Type == ocv1 .ClusterExtensionRevisionTypeAvailable &&
451- cond .Status == corev1 .ConditionTrue &&
452- depl .Status .UpdatedReplicas == * depl .Spec .Replicas {
453- return true , nil
454- }
455- }
456- return false , []string {"not available or not fully updated" }
457- })),
434+ boxcutter .WithProbe (boxcutter .ProgressProbeType , probing.And {
435+ deploymentProbe , statefulSetProbe , crdProbe , issuerProbe , certProbe ,
436+ }),
458437 }
459438
460439 r := & boxcutter.Revision {
@@ -490,3 +469,64 @@ func toBoxcutterRevision(rev *ocv1.ClusterExtensionRevision) (*boxcutter.Revisio
490469 }
491470 return r , opts , previous
492471}
472+
473+ var (
474+ deploymentProbe = & probing.GroupKindSelector {
475+ GroupKind : schema.GroupKind {Group : appsv1 .GroupName , Kind : "Deployment" },
476+ Prober : deplStatefulSetProbe ,
477+ }
478+ statefulSetProbe = & probing.GroupKindSelector {
479+ GroupKind : schema.GroupKind {Group : appsv1 .GroupName , Kind : "StatefulSet" },
480+ Prober : deplStatefulSetProbe ,
481+ }
482+ crdProbe = & probing.GroupKindSelector {
483+ GroupKind : schema.GroupKind {Group : "apiextensions.k8s.io" , Kind : "CustomResourceDefinition" },
484+ Prober : & probing.ObservedGenerationProbe {
485+ Prober : & probing.ConditionProbe { // "Available" == "True"
486+ Type : string (apiextensions .Established ),
487+ Status : string (corev1 .ConditionTrue ),
488+ },
489+ },
490+ }
491+ certProbe = & probing.GroupKindSelector {
492+ GroupKind : schema.GroupKind {Group : "acme.cert-manager.io" , Kind : "Certificate" },
493+ Prober : & probing.ObservedGenerationProbe {
494+ Prober : readyConditionProbe ,
495+ },
496+ }
497+ issuerProbe = & probing.GroupKindSelector {
498+ GroupKind : schema.GroupKind {Group : "acme.cert-manager.io" , Kind : "Issuer" },
499+ Prober : & probing.ObservedGenerationProbe {
500+ Prober : readyConditionProbe ,
501+ },
502+ }
503+
504+ // deplStaefulSetProbe probes Deployment, StatefulSet objects.
505+ deplStatefulSetProbe = & probing.ObservedGenerationProbe {
506+ Prober : probing.And {
507+ availableConditionProbe ,
508+ replicasUpdatedProbe ,
509+ },
510+ }
511+
512+ // Checks if the Type: "Available" Condition is "True".
513+ availableConditionProbe = & probing.ConditionProbe { // "Available" == "True"
514+ Type : string (appsv1 .DeploymentAvailable ),
515+ Status : string (corev1 .ConditionTrue ),
516+ }
517+
518+ // Checks if the Type: "Ready" Condition is "True"
519+ readyConditionProbe = & probing.ObservedGenerationProbe {
520+ Prober : & probing.ConditionProbe {
521+ Type : "Ready" ,
522+ Status : "True" ,
523+ },
524+ }
525+
526+ // Checks if .status.updatedReplicas == .status.replicas.
527+ // Works for StatefulSts, Deployments and ReplicaSets.
528+ replicasUpdatedProbe = & probing.FieldsEqualProbe {
529+ FieldA : ".status.updatedReplicas" ,
530+ FieldB : ".status.replicas" ,
531+ }
532+ )
0 commit comments