@@ -12,16 +12,17 @@ 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/meta"
1617 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1718 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
18- "k8s.io/apimachinery/pkg/runtime"
1919 "k8s.io/apimachinery/pkg/runtime/schema"
2020 "k8s.io/apimachinery/pkg/types"
2121 "k8s.io/apimachinery/pkg/util/sets"
2222 "pkg.package-operator.run/boxcutter"
2323 "pkg.package-operator.run/boxcutter/machinery"
2424 machinerytypes "pkg.package-operator.run/boxcutter/machinery/types"
25+ "pkg.package-operator.run/boxcutter/probing"
2526 ctrl "sigs.k8s.io/controller-runtime"
2627 "sigs.k8s.io/controller-runtime/pkg/builder"
2728 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -373,31 +374,9 @@ func toBoxcutterRevision(rev *ocv1.ClusterExtensionRevision) (*boxcutter.Revisio
373374
374375 opts := []boxcutter.RevisionReconcileOption {
375376 boxcutter .WithPreviousOwners (previous ),
376- boxcutter .WithProbe (boxcutter .ProgressProbeType , boxcutter .ProbeFunc (func (obj client.Object ) (bool , []string ) {
377- deployGK := schema.GroupKind {
378- Group : "apps" , Kind : "Deployment" ,
379- }
380- if obj .GetObjectKind ().GroupVersionKind ().GroupKind () != deployGK {
381- return true , nil
382- }
383- ustrObj := obj .(* unstructured.Unstructured )
384- depl := & appsv1.Deployment {}
385- if err := runtime .DefaultUnstructuredConverter .FromUnstructured (ustrObj .Object , depl ); err != nil {
386- return false , []string {err .Error ()}
387- }
388-
389- if depl .Status .ObservedGeneration != depl .Generation {
390- return false , []string {".status.observedGeneration outdated" }
391- }
392- for _ , cond := range depl .Status .Conditions {
393- if cond .Type == ocv1 .ClusterExtensionRevisionTypeAvailable &&
394- cond .Status == corev1 .ConditionTrue &&
395- depl .Status .UpdatedReplicas == * depl .Spec .Replicas {
396- return true , nil
397- }
398- }
399- return false , []string {"not available or not fully updated" }
400- })),
377+ boxcutter .WithProbe (boxcutter .ProgressProbeType , probing.And {
378+ deploymentProbe , statefulSetProbe , crdProbe , issuerProbe , certProbe ,
379+ }),
401380 }
402381
403382 r := & boxcutter.Revision {
@@ -433,3 +412,64 @@ func toBoxcutterRevision(rev *ocv1.ClusterExtensionRevision) (*boxcutter.Revisio
433412 }
434413 return r , opts , previous
435414}
415+
416+ var (
417+ deploymentProbe = & probing.GroupKindSelector {
418+ GroupKind : schema.GroupKind {Group : appsv1 .GroupName , Kind : "Deployment" },
419+ Prober : deplStatefulSetProbe ,
420+ }
421+ statefulSetProbe = & probing.GroupKindSelector {
422+ GroupKind : schema.GroupKind {Group : appsv1 .GroupName , Kind : "StatefulSet" },
423+ Prober : deplStatefulSetProbe ,
424+ }
425+ crdProbe = & probing.GroupKindSelector {
426+ GroupKind : schema.GroupKind {Group : "apiextensions.k8s.io" , Kind : "CustomResourceDefinition" },
427+ Prober : & probing.ObservedGenerationProbe {
428+ Prober : & probing.ConditionProbe { // "Available" == "True"
429+ Type : string (apiextensions .Established ),
430+ Status : string (corev1 .ConditionTrue ),
431+ },
432+ },
433+ }
434+ certProbe = & probing.GroupKindSelector {
435+ GroupKind : schema.GroupKind {Group : "acme.cert-manager.io" , Kind : "Certificate" },
436+ Prober : & probing.ObservedGenerationProbe {
437+ Prober : readyConditionProbe ,
438+ },
439+ }
440+ issuerProbe = & probing.GroupKindSelector {
441+ GroupKind : schema.GroupKind {Group : "acme.cert-manager.io" , Kind : "Issuer" },
442+ Prober : & probing.ObservedGenerationProbe {
443+ Prober : readyConditionProbe ,
444+ },
445+ }
446+
447+ // deplStaefulSetProbe probes Deployment, StatefulSet objects.
448+ deplStatefulSetProbe = & probing.ObservedGenerationProbe {
449+ Prober : probing.And {
450+ availableConditionProbe ,
451+ replicasUpdatedProbe ,
452+ },
453+ }
454+
455+ // Checks if the Type: "Available" Condition is "True".
456+ availableConditionProbe = & probing.ConditionProbe { // "Available" == "True"
457+ Type : string (appsv1 .DeploymentAvailable ),
458+ Status : string (corev1 .ConditionTrue ),
459+ }
460+
461+ // Checks if the Type: "Ready" Condition is "True"
462+ readyConditionProbe = & probing.ObservedGenerationProbe {
463+ Prober : & probing.ConditionProbe {
464+ Type : "Ready" ,
465+ Status : "True" ,
466+ },
467+ }
468+
469+ // Checks if .status.updatedReplicas == .status.replicas.
470+ // Works for StatefulSts, Deployments and ReplicaSets.
471+ replicasUpdatedProbe = & probing.FieldsEqualProbe {
472+ FieldA : ".status.updatedReplicas" ,
473+ FieldB : ".status.replicas" ,
474+ }
475+ )
0 commit comments