Skip to content
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require (
k8s.io/klog/v2 v2.140.0
k8s.io/kubernetes v1.35.0
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5
pkg.package-operator.run/boxcutter v0.12.0
pkg.package-operator.run/boxcutter v0.13.0
sigs.k8s.io/controller-runtime v0.23.3
sigs.k8s.io/controller-tools v0.20.1
sigs.k8s.io/crdify v0.5.1-0.20260309184313-54162f2e3097
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,8 @@ k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbe
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc=
oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o=
pkg.package-operator.run/boxcutter v0.12.0 h1:9XAi8MjwghfNHyuWzhqrEjY+XIGUz2rg+A72KITb+wA=
pkg.package-operator.run/boxcutter v0.12.0/go.mod h1:Bo1tgiXCYJtehp5p+2aTrKt7VnJhrGKSSBvUQofnDRg=
pkg.package-operator.run/boxcutter v0.13.0 h1:LNUS36NFkI+6J1CcVMrmTOtZt8UoalwXcIDlTPG66C4=
pkg.package-operator.run/boxcutter v0.13.0/go.mod h1:Bo1tgiXCYJtehp5p+2aTrKt7VnJhrGKSSBvUQofnDRg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
Expand Down
63 changes: 0 additions & 63 deletions internal/operator-controller/applier/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@ package applier

import (
"cmp"
"encoding/json"
"fmt"
"slices"
"strings"

"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"pkg.package-operator.run/boxcutter/probing"
"sigs.k8s.io/controller-runtime/pkg/client"

ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1"
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/util"
)

// The following, with modifications, is taken from:
Expand Down Expand Up @@ -206,58 +198,3 @@ func PhaseSort(unsortedObjs []ocv1ac.ClusterObjectSetObjectApplyConfiguration) [

return phasesSorted
}

// FieldValueProbe checks if the value found at FieldPath matches the provided Value
type FieldValueProbe struct {
FieldPath, Value string
}

var _ probing.Prober = (*FieldValueProbe)(nil)

// Probe executes the probe.
func (fe *FieldValueProbe) Probe(obj client.Object) probing.Result {
uMap, err := util.ToUnstructured(obj)
if err != nil {
return probing.UnknownResult(fmt.Sprintf("failed to convert to unstructured: %v", err))
}
return fe.probe(uMap)
}

func (fv *FieldValueProbe) probe(obj *unstructured.Unstructured) probing.Result {
fieldPath := strings.Split(strings.Trim(fv.FieldPath, "."), ".")

fieldVal, ok, err := unstructured.NestedFieldCopy(obj.Object, fieldPath...)
if err != nil {
return probing.Result{
Status: probing.StatusFalse,
Messages: []string{fmt.Sprintf(`error locating key %q; %v`, fv.FieldPath, err)},
}
}
if !ok {
return probing.Result{
Status: probing.StatusFalse,
Messages: []string{fmt.Sprintf(`missing key: %q`, fv.FieldPath)},
}
}

if !equality.Semantic.DeepEqual(fieldVal, fv.Value) {
foundJSON, err := json.Marshal(fieldVal)
if err != nil {
foundJSON = []byte("<value marshal failed>")
}
expectedJSON, err := json.Marshal(fv.Value)
if err != nil {
expectedJSON = []byte("<value marshal failed>")
}

return probing.Result{
Status: probing.StatusFalse,
Messages: []string{fmt.Sprintf(`value at key %q != %q; expected: %s got: %s`, fv.FieldPath, fv.Value, expectedJSON, foundJSON)},
}
}

return probing.Result{
Status: probing.StatusTrue,
Messages: []string{fmt.Sprintf(`value at key %q == %q`, fv.FieldPath, fv.Value)},
}
}
84 changes: 0 additions & 84 deletions internal/operator-controller/applier/phase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@ package applier_test
import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/utils/ptr"
"pkg.package-operator.run/boxcutter/probing"
"sigs.k8s.io/controller-runtime/pkg/client"

ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1"
"github.com/operator-framework/operator-controller/internal/operator-controller/applier"
Expand Down Expand Up @@ -1036,82 +1031,3 @@ func Test_PhaseSort(t *testing.T) {
})
}
}

func Test_FieldValueProbe(t *testing.T) {
for _, tc := range []struct {
name string
obj client.Object
probe applier.FieldValueProbe
expectedResult probing.Result
}{
{
name: "True result with found key and equal value",
obj: &corev1.Service{
TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"},
ObjectMeta: metav1.ObjectMeta{Name: "my-service", Namespace: "my-namespace"},
},
probe: applier.FieldValueProbe{
FieldPath: "metadata.name",
Value: "my-service",
},
expectedResult: probing.Result{
Status: probing.StatusTrue,
Messages: []string{
`value at key "metadata.name" == "my-service"`,
},
},
},
{
name: "False result with unfound key",
obj: &corev1.Service{
TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"},
ObjectMeta: metav1.ObjectMeta{Name: "my-service", Namespace: "my-namespace"},
},
probe: applier.FieldValueProbe{
FieldPath: "spec.foo",
Value: "my-service",
},
expectedResult: probing.Result{
Status: probing.StatusFalse,
Messages: []string{
`missing key: "spec.foo"`,
},
},
},
{
name: "False result with found key and unequal value",
obj: &corev1.Service{
TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"},
ObjectMeta: metav1.ObjectMeta{Name: "my-service", Namespace: "my-namespace"},
},
probe: applier.FieldValueProbe{
FieldPath: "metadata.namespace",
Value: "bar",
},
expectedResult: probing.Result{
Status: probing.StatusFalse,
Messages: []string{
`value at key "metadata.namespace" != "bar"; expected: "bar" got: "my-namespace"`,
},
},
},
{
name: "Unknown result unstructured conversion failure",
obj: nil,
probe: applier.FieldValueProbe{
FieldPath: "metadata.name",
Value: "my-service",
},
expectedResult: probing.Result{
Status: probing.StatusUnknown,
Messages: []string{
"failed to convert to unstructured: object is nil",
},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expectedResult, tc.probe.Probe(tc.obj))
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"

ocv1 "github.com/operator-framework/operator-controller/api/v1"
"github.com/operator-framework/operator-controller/internal/operator-controller/applier"
"github.com/operator-framework/operator-controller/internal/operator-controller/labels"
)

Expand Down Expand Up @@ -643,7 +642,7 @@ func buildProgressionProbes(progressionProbes []ocv1.ProgressionProbe) (probing.
fieldsEqualProbe := probing.FieldsEqualProbe(probe.FieldsEqual)
assertions = append(assertions, &fieldsEqualProbe)
case ocv1.ProbeTypeFieldValue:
fieldValueProbe := applier.FieldValueProbe(probe.FieldValue)
fieldValueProbe := probing.FieldValueProbe(probe.FieldValue)
assertions = append(assertions, &fieldValueProbe)
default:
return nil, fmt.Errorf("unknown progressionProbe assertion probe type: %s", probe.Type)
Expand Down
Loading