From 9c1bf5732300438b32defe48da87517e070e5d2d Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Thu, 23 Dec 2021 14:31:19 -0500 Subject: [PATCH] Switch from Factories to Dies This completes the removal of the factory types that were deprecated in v0.4.0. dies.dev dies are now used as a replacement. Refs #160 Signed-off-by: Scott Andrews --- go.mod | 3 +- go.sum | 6 +- hack/go.mod | 40 +- hack/go.sum | 8 +- hack/tools.go | 6 +- hack/update-codegen.sh | 4 +- internal/resources/dies/dies.go | 60 +++ internal/resources/dies/zz_generated.die.go | 463 ++++++++++++++++++ .../resources/dies/zz_generated.die_test.go | 52 ++ internal/resources/factories/aliases.go | 19 - internal/resources/factories/testresource.go | 128 ----- .../factories/testresource_without_status.go | 84 ---- internal/resources/resource.go | 18 +- reconcilers/.DS_Store | Bin 0 -> 6148 bytes reconcilers/reconcilers_test.go | 344 ++++++++----- testing/factories/clusterrole.go | 89 ---- testing/factories/clusterrolebinding.go | 89 ---- testing/factories/condition.go | 91 ---- testing/factories/configmap.go | 92 ---- testing/factories/deployment.go | 131 ----- testing/factories/ingress.go | 112 ----- testing/factories/objectmeta.go | 159 ------ testing/factories/podtemplatespec.go | 108 ---- testing/factories/role.go | 89 ---- testing/factories/rolebinding.go | 95 ---- testing/factories/secret.go | 98 ---- testing/factories/service.go | 104 ---- testing/factories/serviceaccount.go | 107 ---- testing/factory.go | 29 -- testing/recorder.go | 2 +- testing/subreconciler.go | 8 +- 31 files changed, 878 insertions(+), 1760 deletions(-) create mode 100644 internal/resources/dies/dies.go create mode 100644 internal/resources/dies/zz_generated.die.go create mode 100644 internal/resources/dies/zz_generated.die_test.go delete mode 100644 internal/resources/factories/aliases.go delete mode 100644 internal/resources/factories/testresource.go delete mode 100644 internal/resources/factories/testresource_without_status.go create mode 100644 reconcilers/.DS_Store delete mode 100644 testing/factories/clusterrole.go delete mode 100644 testing/factories/clusterrolebinding.go delete mode 100644 testing/factories/condition.go delete mode 100644 testing/factories/configmap.go delete mode 100644 testing/factories/deployment.go delete mode 100644 testing/factories/ingress.go delete mode 100644 testing/factories/objectmeta.go delete mode 100644 testing/factories/podtemplatespec.go delete mode 100644 testing/factories/role.go delete mode 100644 testing/factories/rolebinding.go delete mode 100644 testing/factories/secret.go delete mode 100644 testing/factories/service.go delete mode 100644 testing/factories/serviceaccount.go delete mode 100644 testing/factory.go diff --git a/go.mod b/go.mod index d612a03..ef1b0f0 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/vmware-labs/reconciler-runtime go 1.17 require ( + dies.dev v0.2.0 github.com/evanphx/json-patch/v5 v5.6.0 github.com/go-logr/logr v1.2.0 github.com/google/go-cmp v0.5.6 @@ -23,7 +24,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/gofuzz v1.1.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.1.2 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/imdario/mergo v0.3.12 // indirect diff --git a/go.sum b/go.sum index c420caa..5e25d65 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dies.dev v0.2.0 h1:qkLFxehtkmBtx+rUMetF8gDyYmS+E6TFwx7xlVzf2Ng= +dies.dev v0.2.0/go.mod h1:9ljRWx1X3zSEtji8mgoG2Y9/yw1HnrHxnyYQpXHMG1g= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -218,8 +220,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -584,6 +587,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/hack/go.mod b/hack/go.mod index df690d0..d63d748 100644 --- a/hack/go.mod +++ b/hack/go.mod @@ -1,5 +1,41 @@ module github.com/vmware-labs/reconciler-runtime/hack -go 1.16 +go 1.17 -require sigs.k8s.io/controller-tools v0.7.0 +require ( + dies.dev/diegen v0.2.0 + sigs.k8s.io/controller-tools v0.7.0 +) + +require ( + github.com/fatih/color v1.12.0 // indirect + github.com/go-logr/logr v0.4.0 // indirect + github.com/gobuffalo/flect v0.2.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/spf13/cobra v1.2.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/mod v0.4.2 // indirect + golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.5 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/api v0.22.2 // indirect + k8s.io/apiextensions-apiserver v0.22.2 // indirect + k8s.io/apimachinery v0.22.2 // indirect + k8s.io/klog/v2 v2.9.0 // indirect + k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect +) diff --git a/hack/go.sum b/hack/go.sum index 92d1c6e..fb852c6 100644 --- a/hack/go.sum +++ b/hack/go.sum @@ -36,6 +36,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dies.dev/diegen v0.2.0 h1:bRldLUKCS0RVKZxipuWNCFFsWeJY0V4baPNULdJdrHo= +dies.dev/diegen v0.2.0/go.mod h1:ZALxA6Wnj2ZikQR6GxYFs9IsRWVQjk8Lg6n4a/nVWjk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -549,8 +551,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b h1:SXy8Ld8oKlcogOvUAh0J5Pm5RKzgYBMMxLxt6n5XW50= +golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -646,8 +649,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/hack/tools.go b/hack/tools.go index 1eaa762..d718a47 100644 --- a/hack/tools.go +++ b/hack/tools.go @@ -1,6 +1,10 @@ +//go:build tools // +build tools // This package imports things required by build scripts, to force `go mod` to see them as dependencies package tools -import _ "sigs.k8s.io/controller-tools/cmd/controller-gen" +import ( + _ "dies.dev/diegen" + _ "sigs.k8s.io/controller-tools/cmd/controller-gen" +) diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 79cf7e8..2c4307a 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -6,5 +6,7 @@ set -o pipefail SCRIPT_ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd) CONTROLLER_GEN="go run -modfile=${SCRIPT_ROOT}/hack/go.mod sigs.k8s.io/controller-tools/cmd/controller-gen" +DIEGEN="go run -modfile=${SCRIPT_ROOT}/hack/go.mod dies.dev/diegen" -( cd $SCRIPT_ROOT ; $CONTROLLER_GEN object:headerFile=./hack/boilerplate.go.txt paths="./..." ) +( cd $SCRIPT_ROOT ; $CONTROLLER_GEN object:headerFile="./hack/boilerplate.go.txt" paths="./..." ) +( cd $SCRIPT_ROOT ; $DIEGEN die:headerFile="./hack/boilerplate.go.txt" paths="./..." ) diff --git a/internal/resources/dies/dies.go b/internal/resources/dies/dies.go new file mode 100644 index 0000000..19e1f9d --- /dev/null +++ b/internal/resources/dies/dies.go @@ -0,0 +1,60 @@ +/* +Copyright 2021 VMware, Inc. +SPDX-License-Identifier: Apache-2.0 +*/ + +package dies + +import ( + diecorev1 "dies.dev/apis/core/v1" + diemetav1 "dies.dev/apis/meta/v1" + "github.com/vmware-labs/reconciler-runtime/internal/resources" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +die:object=true +type _ = resources.TestResource + +// +die +type _ = resources.TestResourceSpec + +func (d *TestResourceSpecDie) AddField(key, value string) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + if r.Fields == nil { + r.Fields = map[string]string{} + } + r.Fields[key] = value + }) +} + +func (d *TestResourceSpecDie) TemplateDie(fn func(d *diecorev1.PodTemplateSpecDie)) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + d := diecorev1.PodTemplateSpecBlank.DieImmutable(false).DieFeed(r.Template) + fn(d) + r.Template = d.DieRelease() + }) +} + +// +die +type _ = resources.TestResourceStatus + +func (d *TestResourceStatusDie) ConditionsDie(conditions ...*diemetav1.ConditionDie) *TestResourceStatusDie { + return d.DieStamp(func(r *resources.TestResourceStatus) { + r.Conditions = make([]metav1.Condition, len(conditions)) + for i := range conditions { + r.Conditions[i] = conditions[i].DieRelease() + } + }) +} + +func (d *TestResourceStatusDie) AddField(key, value string) *TestResourceStatusDie { + return d.DieStamp(func(r *resources.TestResourceStatus) { + if r.Fields == nil { + r.Fields = map[string]string{} + } + r.Fields[key] = value + }) +} + +// +die:object=true +type _ = resources.TestResourceNoStatus diff --git a/internal/resources/dies/zz_generated.die.go b/internal/resources/dies/zz_generated.die.go new file mode 100644 index 0000000..a8b415c --- /dev/null +++ b/internal/resources/dies/zz_generated.die.go @@ -0,0 +1,463 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2020 VMware, Inc. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by diegen. DO NOT EDIT. + +package dies + +import ( + "dies.dev/apis/meta/v1" + json "encoding/json" + fmtx "fmt" + apis "github.com/vmware-labs/reconciler-runtime/apis" + "github.com/vmware-labs/reconciler-runtime/internal/resources" + corev1 "k8s.io/api/core/v1" + unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" +) + +var TestResourceBlank = (&TestResourceDie{}).DieFeed(resources.TestResource{}) + +type TestResourceDie struct { + v1.FrozenObjectMeta + mutable bool + r resources.TestResource +} + +// DieImmutable returns a new die for the current die's state that is either mutable (`false`) or immutable (`true`). +func (d *TestResourceDie) DieImmutable(immutable bool) *TestResourceDie { + if d.mutable == !immutable { + return d + } + d = d.DeepCopy() + d.mutable = !immutable + return d +} + +// DieFeed returns a new die with the provided resource. +func (d *TestResourceDie) DieFeed(r resources.TestResource) *TestResourceDie { + if d.mutable { + d.FrozenObjectMeta = v1.FreezeObjectMeta(r.ObjectMeta) + d.r = r + return d + } + return &TestResourceDie{ + FrozenObjectMeta: v1.FreezeObjectMeta(r.ObjectMeta), + mutable: d.mutable, + r: r, + } +} + +// DieFeedPtr returns a new die with the provided resource pointer. If the resource is nil, the empty value is used instead. +func (d *TestResourceDie) DieFeedPtr(r *resources.TestResource) *TestResourceDie { + if r == nil { + r = &resources.TestResource{} + } + return d.DieFeed(*r) +} + +// DieRelease returns the resource managed by the die. +func (d *TestResourceDie) DieRelease() resources.TestResource { + if d.mutable { + return d.r + } + return *d.r.DeepCopy() +} + +// DieReleasePtr returns a pointer to the resource managed by the die. +func (d *TestResourceDie) DieReleasePtr() *resources.TestResource { + r := d.DieRelease() + return &r +} + +// DieReleaseUnstructured returns the resource managed by the die as an unstructured object. +func (d *TestResourceDie) DieReleaseUnstructured() runtime.Unstructured { + r := d.DieReleasePtr() + u, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(r) + return &unstructured.Unstructured{ + Object: u, + } +} + +// DieStamp returns a new die with the resource passed to the callback function. The resource is mutable. +func (d *TestResourceDie) DieStamp(fn func(r *resources.TestResource)) *TestResourceDie { + r := d.DieRelease() + fn(&r) + return d.DieFeed(r) +} + +// DeepCopy returns a new die with equivalent state. Useful for snapshotting a mutable die. +func (d *TestResourceDie) DeepCopy() *TestResourceDie { + r := *d.r.DeepCopy() + return &TestResourceDie{ + FrozenObjectMeta: v1.FreezeObjectMeta(r.ObjectMeta), + mutable: d.mutable, + r: r, + } +} + +var _ runtime.Object = (*TestResourceDie)(nil) + +func (d *TestResourceDie) DeepCopyObject() runtime.Object { + return d.r.DeepCopy() +} + +func (d *TestResourceDie) GetObjectKind() schema.ObjectKind { + r := d.DieRelease() + return r.GetObjectKind() +} + +func (d *TestResourceDie) MarshalJSON() ([]byte, error) { + return json.Marshal(d.r) +} + +func (d *TestResourceDie) UnmarshalJSON(b []byte) error { + if d == TestResourceBlank { + return fmtx.Errorf("cannot unmarshal into the blank die, create a copy first") + } + if !d.mutable { + return fmtx.Errorf("cannot unmarshal into immutable dies, create a mutable version first") + } + r := &resources.TestResource{} + err := json.Unmarshal(b, r) + *d = *d.DieFeed(*r) + return err +} + +// MetadataDie stamps the resource's ObjectMeta field with a mutable die. +func (d *TestResourceDie) MetadataDie(fn func(d *v1.ObjectMetaDie)) *TestResourceDie { + return d.DieStamp(func(r *resources.TestResource) { + d := v1.ObjectMetaBlank.DieImmutable(false).DieFeed(r.ObjectMeta) + fn(d) + r.ObjectMeta = d.DieRelease() + }) +} + +// SpecDie stamps the resource's spec field with a mutable die. +func (d *TestResourceDie) SpecDie(fn func(d *TestResourceSpecDie)) *TestResourceDie { + return d.DieStamp(func(r *resources.TestResource) { + d := TestResourceSpecBlank.DieImmutable(false).DieFeed(r.Spec) + fn(d) + r.Spec = d.DieRelease() + }) +} + +// StatusDie stamps the resource's status field with a mutable die. +func (d *TestResourceDie) StatusDie(fn func(d *TestResourceStatusDie)) *TestResourceDie { + return d.DieStamp(func(r *resources.TestResource) { + d := TestResourceStatusBlank.DieImmutable(false).DieFeed(r.Status) + fn(d) + r.Status = d.DieRelease() + }) +} + +func (d *TestResourceDie) Spec(v resources.TestResourceSpec) *TestResourceDie { + return d.DieStamp(func(r *resources.TestResource) { + r.Spec = v + }) +} + +func (d *TestResourceDie) Status(v resources.TestResourceStatus) *TestResourceDie { + return d.DieStamp(func(r *resources.TestResource) { + r.Status = v + }) +} + +var TestResourceSpecBlank = (&TestResourceSpecDie{}).DieFeed(resources.TestResourceSpec{}) + +type TestResourceSpecDie struct { + mutable bool + r resources.TestResourceSpec +} + +// DieImmutable returns a new die for the current die's state that is either mutable (`false`) or immutable (`true`). +func (d *TestResourceSpecDie) DieImmutable(immutable bool) *TestResourceSpecDie { + if d.mutable == !immutable { + return d + } + d = d.DeepCopy() + d.mutable = !immutable + return d +} + +// DieFeed returns a new die with the provided resource. +func (d *TestResourceSpecDie) DieFeed(r resources.TestResourceSpec) *TestResourceSpecDie { + if d.mutable { + d.r = r + return d + } + return &TestResourceSpecDie{ + mutable: d.mutable, + r: r, + } +} + +// DieFeedPtr returns a new die with the provided resource pointer. If the resource is nil, the empty value is used instead. +func (d *TestResourceSpecDie) DieFeedPtr(r *resources.TestResourceSpec) *TestResourceSpecDie { + if r == nil { + r = &resources.TestResourceSpec{} + } + return d.DieFeed(*r) +} + +// DieRelease returns the resource managed by the die. +func (d *TestResourceSpecDie) DieRelease() resources.TestResourceSpec { + if d.mutable { + return d.r + } + return *d.r.DeepCopy() +} + +// DieReleasePtr returns a pointer to the resource managed by the die. +func (d *TestResourceSpecDie) DieReleasePtr() *resources.TestResourceSpec { + r := d.DieRelease() + return &r +} + +// DieStamp returns a new die with the resource passed to the callback function. The resource is mutable. +func (d *TestResourceSpecDie) DieStamp(fn func(r *resources.TestResourceSpec)) *TestResourceSpecDie { + r := d.DieRelease() + fn(&r) + return d.DieFeed(r) +} + +// DeepCopy returns a new die with equivalent state. Useful for snapshotting a mutable die. +func (d *TestResourceSpecDie) DeepCopy() *TestResourceSpecDie { + r := *d.r.DeepCopy() + return &TestResourceSpecDie{ + mutable: d.mutable, + r: r, + } +} + +func (d *TestResourceSpecDie) Fields(v map[string]string) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + r.Fields = v + }) +} + +func (d *TestResourceSpecDie) Template(v corev1.PodTemplateSpec) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + r.Template = v + }) +} + +func (d *TestResourceSpecDie) ErrOnMarshal(v bool) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + r.ErrOnMarshal = v + }) +} + +func (d *TestResourceSpecDie) ErrOnUnmarshal(v bool) *TestResourceSpecDie { + return d.DieStamp(func(r *resources.TestResourceSpec) { + r.ErrOnUnmarshal = v + }) +} + +var TestResourceStatusBlank = (&TestResourceStatusDie{}).DieFeed(resources.TestResourceStatus{}) + +type TestResourceStatusDie struct { + mutable bool + r resources.TestResourceStatus +} + +// DieImmutable returns a new die for the current die's state that is either mutable (`false`) or immutable (`true`). +func (d *TestResourceStatusDie) DieImmutable(immutable bool) *TestResourceStatusDie { + if d.mutable == !immutable { + return d + } + d = d.DeepCopy() + d.mutable = !immutable + return d +} + +// DieFeed returns a new die with the provided resource. +func (d *TestResourceStatusDie) DieFeed(r resources.TestResourceStatus) *TestResourceStatusDie { + if d.mutable { + d.r = r + return d + } + return &TestResourceStatusDie{ + mutable: d.mutable, + r: r, + } +} + +// DieFeedPtr returns a new die with the provided resource pointer. If the resource is nil, the empty value is used instead. +func (d *TestResourceStatusDie) DieFeedPtr(r *resources.TestResourceStatus) *TestResourceStatusDie { + if r == nil { + r = &resources.TestResourceStatus{} + } + return d.DieFeed(*r) +} + +// DieRelease returns the resource managed by the die. +func (d *TestResourceStatusDie) DieRelease() resources.TestResourceStatus { + if d.mutable { + return d.r + } + return *d.r.DeepCopy() +} + +// DieReleasePtr returns a pointer to the resource managed by the die. +func (d *TestResourceStatusDie) DieReleasePtr() *resources.TestResourceStatus { + r := d.DieRelease() + return &r +} + +// DieStamp returns a new die with the resource passed to the callback function. The resource is mutable. +func (d *TestResourceStatusDie) DieStamp(fn func(r *resources.TestResourceStatus)) *TestResourceStatusDie { + r := d.DieRelease() + fn(&r) + return d.DieFeed(r) +} + +// DeepCopy returns a new die with equivalent state. Useful for snapshotting a mutable die. +func (d *TestResourceStatusDie) DeepCopy() *TestResourceStatusDie { + r := *d.r.DeepCopy() + return &TestResourceStatusDie{ + mutable: d.mutable, + r: r, + } +} + +func (d *TestResourceStatusDie) Status(v apis.Status) *TestResourceStatusDie { + return d.DieStamp(func(r *resources.TestResourceStatus) { + r.Status = v + }) +} + +func (d *TestResourceStatusDie) Fields(v map[string]string) *TestResourceStatusDie { + return d.DieStamp(func(r *resources.TestResourceStatus) { + r.Fields = v + }) +} + +var TestResourceNoStatusBlank = (&TestResourceNoStatusDie{}).DieFeed(resources.TestResourceNoStatus{}) + +type TestResourceNoStatusDie struct { + v1.FrozenObjectMeta + mutable bool + r resources.TestResourceNoStatus +} + +// DieImmutable returns a new die for the current die's state that is either mutable (`false`) or immutable (`true`). +func (d *TestResourceNoStatusDie) DieImmutable(immutable bool) *TestResourceNoStatusDie { + if d.mutable == !immutable { + return d + } + d = d.DeepCopy() + d.mutable = !immutable + return d +} + +// DieFeed returns a new die with the provided resource. +func (d *TestResourceNoStatusDie) DieFeed(r resources.TestResourceNoStatus) *TestResourceNoStatusDie { + if d.mutable { + d.FrozenObjectMeta = v1.FreezeObjectMeta(r.ObjectMeta) + d.r = r + return d + } + return &TestResourceNoStatusDie{ + FrozenObjectMeta: v1.FreezeObjectMeta(r.ObjectMeta), + mutable: d.mutable, + r: r, + } +} + +// DieFeedPtr returns a new die with the provided resource pointer. If the resource is nil, the empty value is used instead. +func (d *TestResourceNoStatusDie) DieFeedPtr(r *resources.TestResourceNoStatus) *TestResourceNoStatusDie { + if r == nil { + r = &resources.TestResourceNoStatus{} + } + return d.DieFeed(*r) +} + +// DieRelease returns the resource managed by the die. +func (d *TestResourceNoStatusDie) DieRelease() resources.TestResourceNoStatus { + if d.mutable { + return d.r + } + return *d.r.DeepCopy() +} + +// DieReleasePtr returns a pointer to the resource managed by the die. +func (d *TestResourceNoStatusDie) DieReleasePtr() *resources.TestResourceNoStatus { + r := d.DieRelease() + return &r +} + +// DieReleaseUnstructured returns the resource managed by the die as an unstructured object. +func (d *TestResourceNoStatusDie) DieReleaseUnstructured() runtime.Unstructured { + r := d.DieReleasePtr() + u, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(r) + return &unstructured.Unstructured{ + Object: u, + } +} + +// DieStamp returns a new die with the resource passed to the callback function. The resource is mutable. +func (d *TestResourceNoStatusDie) DieStamp(fn func(r *resources.TestResourceNoStatus)) *TestResourceNoStatusDie { + r := d.DieRelease() + fn(&r) + return d.DieFeed(r) +} + +// DeepCopy returns a new die with equivalent state. Useful for snapshotting a mutable die. +func (d *TestResourceNoStatusDie) DeepCopy() *TestResourceNoStatusDie { + r := *d.r.DeepCopy() + return &TestResourceNoStatusDie{ + FrozenObjectMeta: v1.FreezeObjectMeta(r.ObjectMeta), + mutable: d.mutable, + r: r, + } +} + +var _ runtime.Object = (*TestResourceNoStatusDie)(nil) + +func (d *TestResourceNoStatusDie) DeepCopyObject() runtime.Object { + return d.r.DeepCopy() +} + +func (d *TestResourceNoStatusDie) GetObjectKind() schema.ObjectKind { + r := d.DieRelease() + return r.GetObjectKind() +} + +func (d *TestResourceNoStatusDie) MarshalJSON() ([]byte, error) { + return json.Marshal(d.r) +} + +func (d *TestResourceNoStatusDie) UnmarshalJSON(b []byte) error { + if d == TestResourceNoStatusBlank { + return fmtx.Errorf("cannot unmarshal into the blank die, create a copy first") + } + if !d.mutable { + return fmtx.Errorf("cannot unmarshal into immutable dies, create a mutable version first") + } + r := &resources.TestResourceNoStatus{} + err := json.Unmarshal(b, r) + *d = *d.DieFeed(*r) + return err +} + +// MetadataDie stamps the resource's ObjectMeta field with a mutable die. +func (d *TestResourceNoStatusDie) MetadataDie(fn func(d *v1.ObjectMetaDie)) *TestResourceNoStatusDie { + return d.DieStamp(func(r *resources.TestResourceNoStatus) { + d := v1.ObjectMetaBlank.DieImmutable(false).DieFeed(r.ObjectMeta) + fn(d) + r.ObjectMeta = d.DieRelease() + }) +} + +func (d *TestResourceNoStatusDie) Spec(v resources.TestResourceSpec) *TestResourceNoStatusDie { + return d.DieStamp(func(r *resources.TestResourceNoStatus) { + r.Spec = v + }) +} diff --git a/internal/resources/dies/zz_generated.die_test.go b/internal/resources/dies/zz_generated.die_test.go new file mode 100644 index 0000000..746a419 --- /dev/null +++ b/internal/resources/dies/zz_generated.die_test.go @@ -0,0 +1,52 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2020 VMware, Inc. +SPDX-License-Identifier: Apache-2.0 +*/ + +// Code generated by diegen. DO NOT EDIT. + +package dies + +import ( + testing "dies.dev/testing" + testingx "testing" +) + +func TestTestResourceDie_MissingMethods(t *testingx.T) { + die := TestResourceBlank + ignore := []string{"TypeMeta", "ObjectMeta"} + diff := testing.DieFieldDiff(die).Delete(ignore...) + if diff.Len() != 0 { + t.Errorf("found missing fields for TestResourceDie: %s", diff.List()) + } +} + +func TestTestResourceSpecDie_MissingMethods(t *testingx.T) { + die := TestResourceSpecBlank + ignore := []string{} + diff := testing.DieFieldDiff(die).Delete(ignore...) + if diff.Len() != 0 { + t.Errorf("found missing fields for TestResourceSpecDie: %s", diff.List()) + } +} + +func TestTestResourceStatusDie_MissingMethods(t *testingx.T) { + die := TestResourceStatusBlank + ignore := []string{} + diff := testing.DieFieldDiff(die).Delete(ignore...) + if diff.Len() != 0 { + t.Errorf("found missing fields for TestResourceStatusDie: %s", diff.List()) + } +} + +func TestTestResourceNoStatusDie_MissingMethods(t *testingx.T) { + die := TestResourceNoStatusBlank + ignore := []string{"TypeMeta", "ObjectMeta"} + diff := testing.DieFieldDiff(die).Delete(ignore...) + if diff.Len() != 0 { + t.Errorf("found missing fields for TestResourceNoStatusDie: %s", diff.List()) + } +} diff --git a/internal/resources/factories/aliases.go b/internal/resources/factories/aliases.go deleted file mode 100644 index b77e7e0..0000000 --- a/internal/resources/factories/aliases.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2019 VMware, Inc. -SPDX-License-Identifier: Apache-2.0 -*/ - -package factories - -import ( - "github.com/vmware-labs/reconciler-runtime/testing/factories" -) - -type ConditionFactory = factories.ConditionFactory -type ObjectMeta = factories.ObjectMeta -type PodTemplateSpec = factories.PodTemplateSpec - -var Condition = factories.Condition -var ObjectMetaFactory = factories.ObjectMetaFactory -var PodTemplateSpecFactory = factories.PodTemplateSpecFactory -var ConfigMap = factories.ConfigMap diff --git a/internal/resources/factories/testresource.go b/internal/resources/factories/testresource.go deleted file mode 100644 index 2834ddd..0000000 --- a/internal/resources/factories/testresource.go +++ /dev/null @@ -1,128 +0,0 @@ -/* -Copyright 2019 VMware, Inc. -SPDX-License-Identifier: Apache-2.0 -*/ - -package factories - -import ( - "fmt" - - "github.com/vmware-labs/reconciler-runtime/internal/resources" - rtesting "github.com/vmware-labs/reconciler-runtime/testing" - "github.com/vmware-labs/reconciler-runtime/testing/factories" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type testresource struct { - factories.NullObjectMeta - target *resources.TestResource -} - -var ( - _ rtesting.Factory = (*testresource)(nil) - _ client.Object = (*testresource)(nil) -) - -// Deprecated -func TestResource(seed ...*resources.TestResource) *testresource { - var target *resources.TestResource - switch len(seed) { - case 0: - target = &resources.TestResource{} - case 1: - target = seed[0] - default: - panic(fmt.Errorf("expected exactly zero or one seed, got %v", seed)) - } - return &testresource{ - target: target, - } -} - -func (f *testresource) DeepCopyObject() runtime.Object { - return f.CreateObject() -} - -func (f *testresource) GetObjectKind() schema.ObjectKind { - return f.CreateObject().GetObjectKind() -} - -func (f *testresource) deepCopy() *testresource { - return TestResource(f.target.DeepCopy()) -} - -func (f *testresource) Create() *resources.TestResource { - return f.deepCopy().target -} - -func (f *testresource) CreateObject() client.Object { - return f.Create() -} - -func (f *testresource) mutation(m func(*resources.TestResource)) *testresource { - f = f.deepCopy() - m(f.target) - return f -} - -func (f *testresource) NamespaceName(namespace, name string) *testresource { - return f.mutation(func(sa *resources.TestResource) { - sa.ObjectMeta.Namespace = namespace - sa.ObjectMeta.Name = name - }) -} - -func (f *testresource) ObjectMeta(nf func(factories.ObjectMeta)) *testresource { - return f.mutation(func(sa *resources.TestResource) { - omf := factories.ObjectMetaFactory(sa.ObjectMeta) - nf(omf) - sa.ObjectMeta = omf.Create() - }) -} - -func (f *testresource) AddField(key string, value string) *testresource { - return f.mutation(func(r *resources.TestResource) { - if r.Spec.Fields == nil { - r.Spec.Fields = map[string]string{} - } - r.Spec.Fields[key] = value - }) -} - -func (f *testresource) PodTemplateSpec(nf func(factories.PodTemplateSpec)) *testresource { - return f.mutation(func(r *resources.TestResource) { - ptsf := factories.PodTemplateSpecFactory(r.Spec.Template) - nf(ptsf) - r.Spec.Template = ptsf.Create() - }) -} - -func (f *testresource) ErrorOn(marshal, unmarshal bool) *testresource { - return f.mutation(func(r *resources.TestResource) { - r.Spec.ErrOnMarshal = marshal - r.Spec.ErrOnUnmarshal = unmarshal - }) -} - -func (f *testresource) StatusConditions(conditions ...factories.ConditionFactory) *testresource { - return f.mutation(func(testresource *resources.TestResource) { - c := make([]metav1.Condition, len(conditions)) - for i, cg := range conditions { - c[i] = cg.Create() - } - testresource.Status.Conditions = c - }) -} - -func (f *testresource) AddStatusField(key string, value string) *testresource { - return f.mutation(func(r *resources.TestResource) { - if r.Status.Fields == nil { - r.Status.Fields = map[string]string{} - } - r.Status.Fields[key] = value - }) -} diff --git a/internal/resources/factories/testresource_without_status.go b/internal/resources/factories/testresource_without_status.go deleted file mode 100644 index 6fed9ec..0000000 --- a/internal/resources/factories/testresource_without_status.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2021 VMware, Inc. -SPDX-License-Identifier: Apache-2.0 -*/ - -package factories - -import ( - "fmt" - - "github.com/vmware-labs/reconciler-runtime/internal/resources" - rtesting "github.com/vmware-labs/reconciler-runtime/testing" - "github.com/vmware-labs/reconciler-runtime/testing/factories" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type testresourcenostatus struct { - factories.NullObjectMeta - target *resources.TestResourceNoStatus -} - -var ( - _ rtesting.Factory = (*testresourcenostatus)(nil) - _ client.Object = (*testresourcenostatus)(nil) -) - -// Deprecated -func TestResourceNoStatus(seed ...*resources.TestResourceNoStatus) *testresourcenostatus { - var target *resources.TestResourceNoStatus - switch len(seed) { - case 0: - target = &resources.TestResourceNoStatus{} - case 1: - target = seed[0] - default: - panic(fmt.Errorf("expected exactly zero or one seed, got %v", seed)) - } - return &testresourcenostatus{ - target: target, - } -} - -func (f *testresourcenostatus) DeepCopyObject() runtime.Object { - return f.CreateObject() -} - -func (f *testresourcenostatus) GetObjectKind() schema.ObjectKind { - return f.CreateObject().GetObjectKind() -} - -func (f *testresourcenostatus) deepCopy() *testresourcenostatus { - return TestResourceNoStatus(f.target.DeepCopy()) -} - -func (f *testresourcenostatus) Create() *resources.TestResourceNoStatus { - return f.deepCopy().target -} - -func (f *testresourcenostatus) CreateObject() client.Object { - return f.Create() -} - -func (f *testresourcenostatus) mutation(m func(*resources.TestResourceNoStatus)) *testresourcenostatus { - f = f.deepCopy() - m(f.target) - return f -} - -func (f *testresourcenostatus) NamespaceName(namespace, name string) *testresourcenostatus { - return f.mutation(func(sa *resources.TestResourceNoStatus) { - sa.ObjectMeta.Namespace = namespace - sa.ObjectMeta.Name = name - }) -} - -func (f *testresourcenostatus) ObjectMeta(nf func(factories.ObjectMeta)) *testresourcenostatus { - return f.mutation(func(sa *resources.TestResourceNoStatus) { - omf := factories.ObjectMetaFactory(sa.ObjectMeta) - nf(omf) - sa.ObjectMeta = omf.Create() - }) -} diff --git a/internal/resources/resource.go b/internal/resources/resource.go index a8c120b..08b49c5 100644 --- a/internal/resources/resource.go +++ b/internal/resources/resource.go @@ -8,7 +8,6 @@ package resources import ( "encoding/json" "fmt" - "time" "github.com/vmware-labs/reconciler-runtime/apis" "github.com/vmware-labs/reconciler-runtime/validation" @@ -110,8 +109,14 @@ type TestResourceStatus struct { } func (rs *TestResourceStatus) InitializeConditions() { - condSet := apis.NewLivingConditionSetWithHappyReason("Happy") - condSet.Manage(rs).InitializeConditions() + rs.SetConditions([]metav1.Condition{ + { + Type: apis.ConditionReady, + Status: metav1.ConditionUnknown, + Reason: "Initializing", + LastTransitionTime: metav1.Now(), + }, + }) } func (rs *TestResourceStatus) MarkReady() { @@ -119,7 +124,8 @@ func (rs *TestResourceStatus) MarkReady() { { Type: apis.ConditionReady, Status: metav1.ConditionTrue, - LastTransitionTime: metav1.NewTime(time.Now()), + Reason: "Ready", + LastTransitionTime: metav1.Now(), }, }) } @@ -131,11 +137,9 @@ func (rs *TestResourceStatus) MarkNotReady(reason, message string, messageA ...i Status: metav1.ConditionFalse, Reason: reason, Message: fmt.Sprintf(message, messageA...), - LastTransitionTime: metav1.NewTime(time.Now()), + LastTransitionTime: metav1.Now(), }, }) - condSet := apis.NewLivingConditionSetWithHappyReason("Happy") - condSet.Manage(rs).MarkFalse(apis.ConditionReady, reason, message, messageA...) } // +kubebuilder:object:root=true diff --git a/reconcilers/.DS_Store b/reconcilers/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0