From 8a9d8edd7aa27790dbc813d9fcc38677ecf90252 Mon Sep 17 00:00:00 2001 From: Dave Protasowski Date: Fri, 17 Jan 2025 04:48:06 -0500 Subject: [PATCH] use controller tools for schema generation (#931) --- config/300-addressableservice.yaml | 55 +++++-- config/300-simpledeployment.yaml | 52 ++++++- hack/update-codegen.sh | 36 ++--- .../versioned/fake/clientset_generated.go | 6 +- .../samples/v1alpha1/addressableservice.go | 146 ++---------------- .../v1alpha1/fake/fake_addressableservice.go | 36 +++-- .../v1alpha1/fake/fake_simpledeployment.go | 36 +++-- .../samples/v1alpha1/simpledeployment.go | 146 ++---------------- .../informers/externalversions/factory.go | 1 + .../samples/v1alpha1/addressableservice.go | 39 +---- .../samples/v1alpha1/simpledeployment.go | 39 +---- 11 files changed, 186 insertions(+), 406 deletions(-) diff --git a/config/300-addressableservice.yaml b/config/300-addressableservice.yaml index 39c75ae9b..97a7b0801 100644 --- a/config/300-addressableservice.yaml +++ b/config/300-addressableservice.yaml @@ -29,11 +29,33 @@ spec: status: {} schema: openAPIV3Schema: + description: |- + AddressableService is a Knative abstraction that encapsulates the interface by which Knative + components express a desire to have a particular image cached. type: object properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object spec: description: Spec holds the desired state of the AddressableService (from the client). type: object + required: + - serviceName properties: serviceName: description: ServiceName holds the name of the Kubernetes Service to expose as an "addressable". @@ -45,11 +67,11 @@ spec: address: description: Address holds the information needed to connect this Addressable up to receive events. type: object - required: - - url properties: CACerts: - description: CACerts is the Certification Authority (CA) certificates in PEM format according to https://www.rfc-editor.org/rfc/rfc7468. + description: |- + CACerts is the Certification Authority (CA) certificates in PEM format + according to https://www.rfc-editor.org/rfc/rfc7468. type: string audience: description: Audience is the OIDC audience for this address. @@ -60,20 +82,31 @@ spec: url: type: string annotations: - description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards. + description: |- + Annotations is additional Status fields for the Resource to save some + additional State as well as convey more information to the user. This is + roughly akin to Annotations on any k8s resource, just the reconciler conveying + richer information outwards. type: object - x-kubernetes-preserve-unknown-fields: true + additionalProperties: + type: string conditions: description: Conditions the latest available observations of a resource's current state. type: array items: + description: |- + Condition defines a readiness condition for a Knative resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties type: object required: - - type - status + - type properties: lastTransitionTime: - description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant). + description: |- + LastTransitionTime is the last time the condition transitioned from one status to another. + We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic + differences (all other things held constant). type: string message: description: A human readable message indicating details about the transition. @@ -82,7 +115,9 @@ spec: description: The reason for the condition's last transition. type: string severity: - description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error. + description: |- + Severity with which to treat failures of this type of condition. + When this is not specified, it defaults to Error. type: string status: description: Status of the condition, one of True, False, Unknown. @@ -91,7 +126,9 @@ spec: description: Type of condition. type: string observedGeneration: - description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller. + description: |- + ObservedGeneration is the 'Generation' of the Service that + was last processed by the controller. type: integer format: int64 additionalPrinterColumns: diff --git a/config/300-simpledeployment.yaml b/config/300-simpledeployment.yaml index 9c7a71b0a..de425c1d9 100644 --- a/config/300-simpledeployment.yaml +++ b/config/300-simpledeployment.yaml @@ -29,11 +29,34 @@ spec: status: {} schema: openAPIV3Schema: + description: |- + SimpleDeployment is a Knative abstraction that encapsulates the interface by which Knative + components express a desire to have a particular image cached. type: object properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object spec: description: Spec holds the desired state of the SimpleDeployment (from the client). type: object + required: + - image + - replicas properties: image: type: string @@ -43,22 +66,35 @@ spec: status: description: Status communicates the observed state of the SimpleDeployment (from the controller). type: object + required: + - readyReplicas properties: annotations: - description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards. + description: |- + Annotations is additional Status fields for the Resource to save some + additional State as well as convey more information to the user. This is + roughly akin to Annotations on any k8s resource, just the reconciler conveying + richer information outwards. type: object - x-kubernetes-preserve-unknown-fields: true + additionalProperties: + type: string conditions: description: Conditions the latest available observations of a resource's current state. type: array items: + description: |- + Condition defines a readiness condition for a Knative resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties type: object required: - - type - status + - type properties: lastTransitionTime: - description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant). + description: |- + LastTransitionTime is the last time the condition transitioned from one status to another. + We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic + differences (all other things held constant). type: string message: description: A human readable message indicating details about the transition. @@ -67,7 +103,9 @@ spec: description: The reason for the condition's last transition. type: string severity: - description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error. + description: |- + Severity with which to treat failures of this type of condition. + When this is not specified, it defaults to Error. type: string status: description: Status of the condition, one of True, False, Unknown. @@ -76,7 +114,9 @@ spec: description: Type of condition. type: string observedGeneration: - description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller. + description: |- + ObservedGeneration is the 'Generation' of the Service that + was last processed by the controller. type: integer format: int64 readyReplicas: diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 0518a7c8c..aa5d3f6e5 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -21,22 +21,22 @@ set -o pipefail source $(dirname $0)/../vendor/knative.dev/hack/codegen-library.sh export PATH="$GOBIN:$PATH" -function run_yq() { - go_run github.com/mikefarah/yq/v4@v4.23.1 "$@" -} - echo "=== Update Codegen for ${MODULE_NAME}" group "Kubernetes Codegen" -# generate the code with: -# --output-base because this script should also be able to run inside the vendor dir of -# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir -# instead of the $GOPATH directly. For normal projects this can be dropped. -${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ - knative.dev/sample-controller/pkg/client knative.dev/sample-controller/pkg/apis \ - "samples:v1alpha1" \ - --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt +source "${CODEGEN_PKG}/kube_codegen.sh" + +kube::codegen::gen_client \ + --boilerplate "${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt" \ + --output-dir "${REPO_ROOT_DIR}/pkg/client" \ + --output-pkg "knative.dev/sample-controller/pkg/client" \ + --with-watch \ + "${REPO_ROOT_DIR}/pkg/apis" + +kube::codegen::gen_helpers \ + --boilerplate "${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt" \ + "${REPO_ROOT_DIR}/pkg" group "Knative Codegen" @@ -48,15 +48,11 @@ ${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \ group "Update CRD Schema" -go run $(dirname $0)/../cmd/schema/ dump SimpleDeployment \ - | run_yq eval-all --header-preprocess=false --inplace 'select(fileIndex == 0).spec.versions[0].schema.openAPIV3Schema = select(fileIndex == 1) | select(fileIndex == 0)' \ - $(dirname $0)/../config/300-simpledeployment.yaml - - -go run $(dirname $0)/../cmd/schema/ dump AddressableService \ - | run_yq eval-all --header-preprocess=false --inplace 'select(fileIndex == 0).spec.versions[0].schema.openAPIV3Schema = select(fileIndex == 1) | select(fileIndex == 0)' \ - $(dirname $0)/../config/300-addressableservice.yaml - +go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.17.1 \ + schemapatch:manifests=config,generateEmbeddedObjectMeta=true \ + output:dir=config/ \ + paths=./pkg/apis/... group "Update deps post-codegen" - # Make sure our dependencies are up-to-date ${REPO_ROOT_DIR}/hack/update-deps.sh diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 4e148364b..cc34d8b76 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -31,8 +31,12 @@ import ( // NewSimpleClientset returns a clientset that will respond with the provided objects. // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, -// without applying any validations and/or defaults. It shouldn't be considered a replacement +// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// DEPRECATED: NewClientset replaces this with support for field management, which significantly improves +// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. +// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { diff --git a/pkg/client/clientset/versioned/typed/samples/v1alpha1/addressableservice.go b/pkg/client/clientset/versioned/typed/samples/v1alpha1/addressableservice.go index cdd585e19..78a08abd0 100644 --- a/pkg/client/clientset/versioned/typed/samples/v1alpha1/addressableservice.go +++ b/pkg/client/clientset/versioned/typed/samples/v1alpha1/addressableservice.go @@ -20,12 +20,11 @@ package v1alpha1 import ( "context" - "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" v1alpha1 "knative.dev/sample-controller/pkg/apis/samples/v1alpha1" scheme "knative.dev/sample-controller/pkg/client/clientset/versioned/scheme" ) @@ -40,6 +39,7 @@ type AddressableServicesGetter interface { type AddressableServiceInterface interface { Create(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.CreateOptions) (*v1alpha1.AddressableService, error) Update(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (*v1alpha1.AddressableService, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). UpdateStatus(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (*v1alpha1.AddressableService, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error @@ -52,144 +52,18 @@ type AddressableServiceInterface interface { // addressableServices implements AddressableServiceInterface type addressableServices struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.AddressableService, *v1alpha1.AddressableServiceList] } // newAddressableServices returns a AddressableServices func newAddressableServices(c *SamplesV1alpha1Client, namespace string) *addressableServices { return &addressableServices{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.AddressableService, *v1alpha1.AddressableServiceList]( + "addressableservices", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.AddressableService { return &v1alpha1.AddressableService{} }, + func() *v1alpha1.AddressableServiceList { return &v1alpha1.AddressableServiceList{} }), } } - -// Get takes name of the addressableService, and returns the corresponding addressableService object, and an error if there is any. -func (c *addressableServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AddressableService, err error) { - result = &v1alpha1.AddressableService{} - err = c.client.Get(). - Namespace(c.ns). - Resource("addressableservices"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of AddressableServices that match those selectors. -func (c *addressableServices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AddressableServiceList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.AddressableServiceList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("addressableservices"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested addressableServices. -func (c *addressableServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("addressableservices"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a addressableService and creates it. Returns the server's representation of the addressableService, and an error, if there is any. -func (c *addressableServices) Create(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.CreateOptions) (result *v1alpha1.AddressableService, err error) { - result = &v1alpha1.AddressableService{} - err = c.client.Post(). - Namespace(c.ns). - Resource("addressableservices"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(addressableService). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a addressableService and updates it. Returns the server's representation of the addressableService, and an error, if there is any. -func (c *addressableServices) Update(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (result *v1alpha1.AddressableService, err error) { - result = &v1alpha1.AddressableService{} - err = c.client.Put(). - Namespace(c.ns). - Resource("addressableservices"). - Name(addressableService.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(addressableService). - Do(ctx). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *addressableServices) UpdateStatus(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (result *v1alpha1.AddressableService, err error) { - result = &v1alpha1.AddressableService{} - err = c.client.Put(). - Namespace(c.ns). - Resource("addressableservices"). - Name(addressableService.Name). - SubResource("status"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(addressableService). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the addressableService and deletes it. Returns an error if one occurs. -func (c *addressableServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("addressableservices"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *addressableServices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("addressableservices"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched addressableService. -func (c *addressableServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AddressableService, err error) { - result = &v1alpha1.AddressableService{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("addressableservices"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_addressableservice.go b/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_addressableservice.go index b8c603c62..b3cc03e6b 100644 --- a/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_addressableservice.go +++ b/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_addressableservice.go @@ -41,22 +41,24 @@ var addressableservicesKind = v1alpha1.SchemeGroupVersion.WithKind("AddressableS // Get takes name of the addressableService, and returns the corresponding addressableService object, and an error if there is any. func (c *FakeAddressableServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AddressableService, err error) { + emptyResult := &v1alpha1.AddressableService{} obj, err := c.Fake. - Invokes(testing.NewGetAction(addressableservicesResource, c.ns, name), &v1alpha1.AddressableService{}) + Invokes(testing.NewGetActionWithOptions(addressableservicesResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AddressableService), err } // List takes label and field selectors, and returns the list of AddressableServices that match those selectors. func (c *FakeAddressableServices) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AddressableServiceList, err error) { + emptyResult := &v1alpha1.AddressableServiceList{} obj, err := c.Fake. - Invokes(testing.NewListAction(addressableservicesResource, addressableservicesKind, c.ns, opts), &v1alpha1.AddressableServiceList{}) + Invokes(testing.NewListActionWithOptions(addressableservicesResource, addressableservicesKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -75,40 +77,43 @@ func (c *FakeAddressableServices) List(ctx context.Context, opts v1.ListOptions) // Watch returns a watch.Interface that watches the requested addressableServices. func (c *FakeAddressableServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(addressableservicesResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(addressableservicesResource, c.ns, opts)) } // Create takes the representation of a addressableService and creates it. Returns the server's representation of the addressableService, and an error, if there is any. func (c *FakeAddressableServices) Create(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.CreateOptions) (result *v1alpha1.AddressableService, err error) { + emptyResult := &v1alpha1.AddressableService{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(addressableservicesResource, c.ns, addressableService), &v1alpha1.AddressableService{}) + Invokes(testing.NewCreateActionWithOptions(addressableservicesResource, c.ns, addressableService, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AddressableService), err } // Update takes the representation of a addressableService and updates it. Returns the server's representation of the addressableService, and an error, if there is any. func (c *FakeAddressableServices) Update(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (result *v1alpha1.AddressableService, err error) { + emptyResult := &v1alpha1.AddressableService{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(addressableservicesResource, c.ns, addressableService), &v1alpha1.AddressableService{}) + Invokes(testing.NewUpdateActionWithOptions(addressableservicesResource, c.ns, addressableService, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AddressableService), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeAddressableServices) UpdateStatus(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (*v1alpha1.AddressableService, error) { +func (c *FakeAddressableServices) UpdateStatus(ctx context.Context, addressableService *v1alpha1.AddressableService, opts v1.UpdateOptions) (result *v1alpha1.AddressableService, err error) { + emptyResult := &v1alpha1.AddressableService{} obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(addressableservicesResource, "status", c.ns, addressableService), &v1alpha1.AddressableService{}) + Invokes(testing.NewUpdateSubresourceActionWithOptions(addressableservicesResource, "status", c.ns, addressableService, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AddressableService), err } @@ -123,7 +128,7 @@ func (c *FakeAddressableServices) Delete(ctx context.Context, name string, opts // DeleteCollection deletes a collection of objects. func (c *FakeAddressableServices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(addressableservicesResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(addressableservicesResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.AddressableServiceList{}) return err @@ -131,11 +136,12 @@ func (c *FakeAddressableServices) DeleteCollection(ctx context.Context, opts v1. // Patch applies the patch and returns the patched addressableService. func (c *FakeAddressableServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AddressableService, err error) { + emptyResult := &v1alpha1.AddressableService{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(addressableservicesResource, c.ns, name, pt, data, subresources...), &v1alpha1.AddressableService{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(addressableservicesResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AddressableService), err } diff --git a/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_simpledeployment.go b/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_simpledeployment.go index e267fb6ed..450fca18a 100644 --- a/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_simpledeployment.go +++ b/pkg/client/clientset/versioned/typed/samples/v1alpha1/fake/fake_simpledeployment.go @@ -41,22 +41,24 @@ var simpledeploymentsKind = v1alpha1.SchemeGroupVersion.WithKind("SimpleDeployme // Get takes name of the simpleDeployment, and returns the corresponding simpleDeployment object, and an error if there is any. func (c *FakeSimpleDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.SimpleDeployment, err error) { + emptyResult := &v1alpha1.SimpleDeployment{} obj, err := c.Fake. - Invokes(testing.NewGetAction(simpledeploymentsResource, c.ns, name), &v1alpha1.SimpleDeployment{}) + Invokes(testing.NewGetActionWithOptions(simpledeploymentsResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.SimpleDeployment), err } // List takes label and field selectors, and returns the list of SimpleDeployments that match those selectors. func (c *FakeSimpleDeployments) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.SimpleDeploymentList, err error) { + emptyResult := &v1alpha1.SimpleDeploymentList{} obj, err := c.Fake. - Invokes(testing.NewListAction(simpledeploymentsResource, simpledeploymentsKind, c.ns, opts), &v1alpha1.SimpleDeploymentList{}) + Invokes(testing.NewListActionWithOptions(simpledeploymentsResource, simpledeploymentsKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -75,40 +77,43 @@ func (c *FakeSimpleDeployments) List(ctx context.Context, opts v1.ListOptions) ( // Watch returns a watch.Interface that watches the requested simpleDeployments. func (c *FakeSimpleDeployments) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(simpledeploymentsResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(simpledeploymentsResource, c.ns, opts)) } // Create takes the representation of a simpleDeployment and creates it. Returns the server's representation of the simpleDeployment, and an error, if there is any. func (c *FakeSimpleDeployments) Create(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.CreateOptions) (result *v1alpha1.SimpleDeployment, err error) { + emptyResult := &v1alpha1.SimpleDeployment{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(simpledeploymentsResource, c.ns, simpleDeployment), &v1alpha1.SimpleDeployment{}) + Invokes(testing.NewCreateActionWithOptions(simpledeploymentsResource, c.ns, simpleDeployment, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.SimpleDeployment), err } // Update takes the representation of a simpleDeployment and updates it. Returns the server's representation of the simpleDeployment, and an error, if there is any. func (c *FakeSimpleDeployments) Update(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (result *v1alpha1.SimpleDeployment, err error) { + emptyResult := &v1alpha1.SimpleDeployment{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(simpledeploymentsResource, c.ns, simpleDeployment), &v1alpha1.SimpleDeployment{}) + Invokes(testing.NewUpdateActionWithOptions(simpledeploymentsResource, c.ns, simpleDeployment, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.SimpleDeployment), err } // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeSimpleDeployments) UpdateStatus(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (*v1alpha1.SimpleDeployment, error) { +func (c *FakeSimpleDeployments) UpdateStatus(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (result *v1alpha1.SimpleDeployment, err error) { + emptyResult := &v1alpha1.SimpleDeployment{} obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(simpledeploymentsResource, "status", c.ns, simpleDeployment), &v1alpha1.SimpleDeployment{}) + Invokes(testing.NewUpdateSubresourceActionWithOptions(simpledeploymentsResource, "status", c.ns, simpleDeployment, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.SimpleDeployment), err } @@ -123,7 +128,7 @@ func (c *FakeSimpleDeployments) Delete(ctx context.Context, name string, opts v1 // DeleteCollection deletes a collection of objects. func (c *FakeSimpleDeployments) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(simpledeploymentsResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(simpledeploymentsResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.SimpleDeploymentList{}) return err @@ -131,11 +136,12 @@ func (c *FakeSimpleDeployments) DeleteCollection(ctx context.Context, opts v1.De // Patch applies the patch and returns the patched simpleDeployment. func (c *FakeSimpleDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.SimpleDeployment, err error) { + emptyResult := &v1alpha1.SimpleDeployment{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(simpledeploymentsResource, c.ns, name, pt, data, subresources...), &v1alpha1.SimpleDeployment{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(simpledeploymentsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.SimpleDeployment), err } diff --git a/pkg/client/clientset/versioned/typed/samples/v1alpha1/simpledeployment.go b/pkg/client/clientset/versioned/typed/samples/v1alpha1/simpledeployment.go index 5bfc0cf57..016b99ec6 100644 --- a/pkg/client/clientset/versioned/typed/samples/v1alpha1/simpledeployment.go +++ b/pkg/client/clientset/versioned/typed/samples/v1alpha1/simpledeployment.go @@ -20,12 +20,11 @@ package v1alpha1 import ( "context" - "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" v1alpha1 "knative.dev/sample-controller/pkg/apis/samples/v1alpha1" scheme "knative.dev/sample-controller/pkg/client/clientset/versioned/scheme" ) @@ -40,6 +39,7 @@ type SimpleDeploymentsGetter interface { type SimpleDeploymentInterface interface { Create(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.CreateOptions) (*v1alpha1.SimpleDeployment, error) Update(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (*v1alpha1.SimpleDeployment, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). UpdateStatus(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (*v1alpha1.SimpleDeployment, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error @@ -52,144 +52,18 @@ type SimpleDeploymentInterface interface { // simpleDeployments implements SimpleDeploymentInterface type simpleDeployments struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.SimpleDeployment, *v1alpha1.SimpleDeploymentList] } // newSimpleDeployments returns a SimpleDeployments func newSimpleDeployments(c *SamplesV1alpha1Client, namespace string) *simpleDeployments { return &simpleDeployments{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.SimpleDeployment, *v1alpha1.SimpleDeploymentList]( + "simpledeployments", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.SimpleDeployment { return &v1alpha1.SimpleDeployment{} }, + func() *v1alpha1.SimpleDeploymentList { return &v1alpha1.SimpleDeploymentList{} }), } } - -// Get takes name of the simpleDeployment, and returns the corresponding simpleDeployment object, and an error if there is any. -func (c *simpleDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.SimpleDeployment, err error) { - result = &v1alpha1.SimpleDeployment{} - err = c.client.Get(). - Namespace(c.ns). - Resource("simpledeployments"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of SimpleDeployments that match those selectors. -func (c *simpleDeployments) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.SimpleDeploymentList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.SimpleDeploymentList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("simpledeployments"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested simpleDeployments. -func (c *simpleDeployments) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("simpledeployments"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a simpleDeployment and creates it. Returns the server's representation of the simpleDeployment, and an error, if there is any. -func (c *simpleDeployments) Create(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.CreateOptions) (result *v1alpha1.SimpleDeployment, err error) { - result = &v1alpha1.SimpleDeployment{} - err = c.client.Post(). - Namespace(c.ns). - Resource("simpledeployments"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(simpleDeployment). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a simpleDeployment and updates it. Returns the server's representation of the simpleDeployment, and an error, if there is any. -func (c *simpleDeployments) Update(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (result *v1alpha1.SimpleDeployment, err error) { - result = &v1alpha1.SimpleDeployment{} - err = c.client.Put(). - Namespace(c.ns). - Resource("simpledeployments"). - Name(simpleDeployment.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(simpleDeployment). - Do(ctx). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *simpleDeployments) UpdateStatus(ctx context.Context, simpleDeployment *v1alpha1.SimpleDeployment, opts v1.UpdateOptions) (result *v1alpha1.SimpleDeployment, err error) { - result = &v1alpha1.SimpleDeployment{} - err = c.client.Put(). - Namespace(c.ns). - Resource("simpledeployments"). - Name(simpleDeployment.Name). - SubResource("status"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(simpleDeployment). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the simpleDeployment and deletes it. Returns an error if one occurs. -func (c *simpleDeployments) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("simpledeployments"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *simpleDeployments) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("simpledeployments"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched simpleDeployment. -func (c *simpleDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.SimpleDeployment, err error) { - result = &v1alpha1.SimpleDeployment{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("simpledeployments"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 9f8b3b348..d32f0e547 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -228,6 +228,7 @@ type SharedInformerFactory interface { // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. + // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. Start(stopCh <-chan struct{}) // Shutdown marks a factory as shutting down. At that point no new diff --git a/pkg/client/listers/samples/v1alpha1/addressableservice.go b/pkg/client/listers/samples/v1alpha1/addressableservice.go index 94d297954..053746ac6 100644 --- a/pkg/client/listers/samples/v1alpha1/addressableservice.go +++ b/pkg/client/listers/samples/v1alpha1/addressableservice.go @@ -19,8 +19,8 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" v1alpha1 "knative.dev/sample-controller/pkg/apis/samples/v1alpha1" ) @@ -38,25 +38,17 @@ type AddressableServiceLister interface { // addressableServiceLister implements the AddressableServiceLister interface. type addressableServiceLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.AddressableService] } // NewAddressableServiceLister returns a new AddressableServiceLister. func NewAddressableServiceLister(indexer cache.Indexer) AddressableServiceLister { - return &addressableServiceLister{indexer: indexer} -} - -// List lists all AddressableServices in the indexer. -func (s *addressableServiceLister) List(selector labels.Selector) (ret []*v1alpha1.AddressableService, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AddressableService)) - }) - return ret, err + return &addressableServiceLister{listers.New[*v1alpha1.AddressableService](indexer, v1alpha1.Resource("addressableservice"))} } // AddressableServices returns an object that can list and get AddressableServices. func (s *addressableServiceLister) AddressableServices(namespace string) AddressableServiceNamespaceLister { - return addressableServiceNamespaceLister{indexer: s.indexer, namespace: namespace} + return addressableServiceNamespaceLister{listers.NewNamespaced[*v1alpha1.AddressableService](s.ResourceIndexer, namespace)} } // AddressableServiceNamespaceLister helps list and get AddressableServices. @@ -74,26 +66,5 @@ type AddressableServiceNamespaceLister interface { // addressableServiceNamespaceLister implements the AddressableServiceNamespaceLister // interface. type addressableServiceNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all AddressableServices in the indexer for a given namespace. -func (s addressableServiceNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.AddressableService, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AddressableService)) - }) - return ret, err -} - -// Get retrieves the AddressableService from the indexer for a given namespace and name. -func (s addressableServiceNamespaceLister) Get(name string) (*v1alpha1.AddressableService, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("addressableservice"), name) - } - return obj.(*v1alpha1.AddressableService), nil + listers.ResourceIndexer[*v1alpha1.AddressableService] } diff --git a/pkg/client/listers/samples/v1alpha1/simpledeployment.go b/pkg/client/listers/samples/v1alpha1/simpledeployment.go index 9ebdd4507..daf28f51e 100644 --- a/pkg/client/listers/samples/v1alpha1/simpledeployment.go +++ b/pkg/client/listers/samples/v1alpha1/simpledeployment.go @@ -19,8 +19,8 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" v1alpha1 "knative.dev/sample-controller/pkg/apis/samples/v1alpha1" ) @@ -38,25 +38,17 @@ type SimpleDeploymentLister interface { // simpleDeploymentLister implements the SimpleDeploymentLister interface. type simpleDeploymentLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.SimpleDeployment] } // NewSimpleDeploymentLister returns a new SimpleDeploymentLister. func NewSimpleDeploymentLister(indexer cache.Indexer) SimpleDeploymentLister { - return &simpleDeploymentLister{indexer: indexer} -} - -// List lists all SimpleDeployments in the indexer. -func (s *simpleDeploymentLister) List(selector labels.Selector) (ret []*v1alpha1.SimpleDeployment, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.SimpleDeployment)) - }) - return ret, err + return &simpleDeploymentLister{listers.New[*v1alpha1.SimpleDeployment](indexer, v1alpha1.Resource("simpledeployment"))} } // SimpleDeployments returns an object that can list and get SimpleDeployments. func (s *simpleDeploymentLister) SimpleDeployments(namespace string) SimpleDeploymentNamespaceLister { - return simpleDeploymentNamespaceLister{indexer: s.indexer, namespace: namespace} + return simpleDeploymentNamespaceLister{listers.NewNamespaced[*v1alpha1.SimpleDeployment](s.ResourceIndexer, namespace)} } // SimpleDeploymentNamespaceLister helps list and get SimpleDeployments. @@ -74,26 +66,5 @@ type SimpleDeploymentNamespaceLister interface { // simpleDeploymentNamespaceLister implements the SimpleDeploymentNamespaceLister // interface. type simpleDeploymentNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all SimpleDeployments in the indexer for a given namespace. -func (s simpleDeploymentNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.SimpleDeployment, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.SimpleDeployment)) - }) - return ret, err -} - -// Get retrieves the SimpleDeployment from the indexer for a given namespace and name. -func (s simpleDeploymentNamespaceLister) Get(name string) (*v1alpha1.SimpleDeployment, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("simpledeployment"), name) - } - return obj.(*v1alpha1.SimpleDeployment), nil + listers.ResourceIndexer[*v1alpha1.SimpleDeployment] }