From 500744bb94deab2923b36de8f713a06e329da473 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Fri, 8 Sep 2023 16:35:14 +0000 Subject: [PATCH] Add new CRD for etcd snapshots Also adds a hack go script to print the embedded CRDs, for developer use. Signed-off-by: Brad Davidson --- hack/crdgen.go | 13 ++ pkg/apis/k3s.cattle.io/v1/types.go | 89 ++++++++- .../k3s.cattle.io/v1/zz_generated_deepcopy.go | 165 ++++++++++++++++ .../v1/zz_generated_list_types.go | 17 ++ .../k3s.cattle.io/v1/zz_generated_register.go | 5 +- pkg/codegen/main.go | 1 + pkg/crd/crds.go | 21 +- .../k3s.cattle.io/v1/etcdsnapshotfile.go | 184 ++++++++++++++++++ .../v1/fake/fake_etcdsnapshotfile.go | 132 +++++++++++++ .../v1/fake/fake_k3s.cattle.io_client.go | 4 + .../k3s.cattle.io/v1/generated_expansion.go | 2 + .../k3s.cattle.io/v1/k3s.cattle.io_client.go | 5 + .../k3s.cattle.io/v1/etcdsnapshotfile.go | 161 +++++++++++++++ .../controllers/k3s.cattle.io/v1/interface.go | 5 + 14 files changed, 795 insertions(+), 9 deletions(-) create mode 100644 hack/crdgen.go create mode 100644 pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/etcdsnapshotfile.go create mode 100644 pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_etcdsnapshotfile.go create mode 100644 pkg/generated/controllers/k3s.cattle.io/v1/etcdsnapshotfile.go diff --git a/hack/crdgen.go b/hack/crdgen.go new file mode 100644 index 0000000000..fed1083d0b --- /dev/null +++ b/hack/crdgen.go @@ -0,0 +1,13 @@ +package main + +import ( + "os" + + k3scrd "github.com/k3s-io/k3s/pkg/crd" + _ "github.com/k3s-io/k3s/pkg/generated/controllers/k3s.cattle.io/v1" + "github.com/rancher/wrangler/pkg/crd" +) + +func main() { + crd.Print(os.Stdout, k3scrd.List()) +} diff --git a/pkg/apis/k3s.cattle.io/v1/types.go b/pkg/apis/k3s.cattle.io/v1/types.go index 79ae04f77a..c52e8eee51 100644 --- a/pkg/apis/k3s.cattle.io/v1/types.go +++ b/pkg/apis/k3s.cattle.io/v1/types.go @@ -1,20 +1,105 @@ package v1 import ( + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +genclient +// +genclient:noStatus // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// Addon is used to track application of a manifest file on disk. It mostly exists so that the wrangler DesiredSet +// Apply controller has an object to track as the owner, and ensure that all created resources are tracked when the +// manifest is modified or removed. type Addon struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // Spec provides information about the on-disk manifest backing this resource. Spec AddonSpec `json:"spec,omitempty"` } type AddonSpec struct { - Source string `json:"source,omitempty"` - Checksum string `json:"checksum,omitempty"` + // Source is the Path on disk to the manifest file that this Addon tracks. + Source string `json:"source,omitempty" column:""` + // Checksum is the SHA256 checksum of the most recently successfully applied manifest file. + Checksum string `json:"checksum,omitempty" column:""` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ETCDSnapshot tracks a point-in-time snapshot of the etcd datastore. +type ETCDSnapshotFile struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines properties of an etcd snapshot file + Spec ETCDSnapshotSpec `json:"spec,omitempty"` + // Status represents current information about a snapshot. + Status ETCDSnapshotStatus `json:"status,omitempty"` +} + +// ETCDSnapshotSpec desribes an etcd snapshot file +type ETCDSnapshotSpec struct { + // SnapshotName contains the base name of the snapshot file. CLI actions that act + // on snapshots stored locally or within a pre-configured S3 bucket and + // prefix usually take the snapshot name as their argument. + SnapshotName string `json:"snapshotName" column:""` + // NodeName contains the name of the node that took the snapshot. + NodeName string `json:"nodeName" column:"name=Node"` + // Location is the absolute file:// or s3:// URI address of the snapshot. + Location string `json:"location" column:""` + // Metadata contains point-in-time snapshot of the contents of the + // k3s-etcd-snapshot-extra-metadata ConfigMap's data field, at the time the + // snapshot was taken. This is intended to contain data about cluster state + // that may be important for an external system to have available when restoring + // the snapshot. + Metadata map[string]string `json:"metadata,omitempty"` + // S3 contains extra metadata about the S3 storage system holding the + // snapshot. This is guaranteed to be set for all snapshots uploaded to S3. + // If not specified, the snapshot was not uploaded to S3. + S3 *ETCDSnapshotS3 `json:"s3,omitempty"` +} + +// ETCDSnapshotS3 holds information about the S3 storage system holding the snapshot. +type ETCDSnapshotS3 struct { + // Endpoint is the host or host:port of the S3 service + Endpoint string `json:"endpoint,omitempty"` + // EndpointCA is the path on disk to the S3 service's trusted CA list. Leave empty to use the OS CA bundle. + EndpointCA string `json:"endpointCA,omitempty"` + // SkipSSLVerify is true if TLS certificate verification is disabled + SkipSSLVerify bool `json:"skipSSLVerify,omitempty"` + // Bucket is the bucket holding the snapshot + Bucket string `json:"bucket,omitempty"` + // Region is the region of the S3 service + Region string `json:"region,omitempty"` + // Prefix is the prefix in which the snapshot file is stored. + Prefix string `json:"prefix,omitempty"` + // Insecure is true if the S3 service uses HTTP instead of HTTPS + Insecure bool `json:"insecure,omitempty"` +} + +// ETCDSnapshotStatus is the status of the ETCDSnapshotFile object. +type ETCDSnapshotStatus struct { + // Size is the size of the snapshot file, in bytes. If not specified, the snapshot failed. + Size *resource.Quantity `json:"size,omitempty" column:""` + // CreationTime is the timestamp when the snapshot was taken by etcd. + CreationTime *metav1.Time `json:"creationTime,omitempty" column:""` + // ReadyToUse indicates that the snapshot is available to be restored. + ReadyToUse *bool `json:"readyToUse,omitempty"` + // Error is the last observed error during snapshot creation, if any. + // If the snapshot is retried, this field will be cleared on success. + Error *ETCDSnapshotError `json:"error,omitempty"` +} + +// ETCDSnapshotError describes an error encountered during snapshot creation. +type ETCDSnapshotError struct { + // Time is the timestamp when the error was encountered. + Time *metav1.Time `json:"time,omitempty"` + // Message is a string detailing the encountered error during snapshot creation if specified. + // NOTE: message may be logged, and it should not contain sensitive information. + Message *string `json:"message,omitempty"` } diff --git a/pkg/apis/k3s.cattle.io/v1/zz_generated_deepcopy.go b/pkg/apis/k3s.cattle.io/v1/zz_generated_deepcopy.go index 69011aa78d..1679c1e7ff 100644 --- a/pkg/apis/k3s.cattle.io/v1/zz_generated_deepcopy.go +++ b/pkg/apis/k3s.cattle.io/v1/zz_generated_deepcopy.go @@ -100,3 +100,168 @@ func (in *AddonSpec) DeepCopy() *AddonSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotError) DeepCopyInto(out *ETCDSnapshotError) { + *out = *in + if in.Time != nil { + in, out := &in.Time, &out.Time + *out = (*in).DeepCopy() + } + if in.Message != nil { + in, out := &in.Message, &out.Message + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotError. +func (in *ETCDSnapshotError) DeepCopy() *ETCDSnapshotError { + if in == nil { + return nil + } + out := new(ETCDSnapshotError) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotFile) DeepCopyInto(out *ETCDSnapshotFile) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotFile. +func (in *ETCDSnapshotFile) DeepCopy() *ETCDSnapshotFile { + if in == nil { + return nil + } + out := new(ETCDSnapshotFile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ETCDSnapshotFile) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotFileList) DeepCopyInto(out *ETCDSnapshotFileList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ETCDSnapshotFile, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotFileList. +func (in *ETCDSnapshotFileList) DeepCopy() *ETCDSnapshotFileList { + if in == nil { + return nil + } + out := new(ETCDSnapshotFileList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ETCDSnapshotFileList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotS3) DeepCopyInto(out *ETCDSnapshotS3) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotS3. +func (in *ETCDSnapshotS3) DeepCopy() *ETCDSnapshotS3 { + if in == nil { + return nil + } + out := new(ETCDSnapshotS3) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotSpec) DeepCopyInto(out *ETCDSnapshotSpec) { + *out = *in + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(ETCDSnapshotS3) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotSpec. +func (in *ETCDSnapshotSpec) DeepCopy() *ETCDSnapshotSpec { + if in == nil { + return nil + } + out := new(ETCDSnapshotSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotStatus) DeepCopyInto(out *ETCDSnapshotStatus) { + *out = *in + if in.Size != nil { + in, out := &in.Size, &out.Size + x := (*in).DeepCopy() + *out = &x + } + if in.CreationTime != nil { + in, out := &in.CreationTime, &out.CreationTime + *out = (*in).DeepCopy() + } + if in.ReadyToUse != nil { + in, out := &in.ReadyToUse, &out.ReadyToUse + *out = new(bool) + **out = **in + } + if in.Error != nil { + in, out := &in.Error, &out.Error + *out = new(ETCDSnapshotError) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotStatus. +func (in *ETCDSnapshotStatus) DeepCopy() *ETCDSnapshotStatus { + if in == nil { + return nil + } + out := new(ETCDSnapshotStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/k3s.cattle.io/v1/zz_generated_list_types.go b/pkg/apis/k3s.cattle.io/v1/zz_generated_list_types.go index 5295502863..c00d6ac70a 100644 --- a/pkg/apis/k3s.cattle.io/v1/zz_generated_list_types.go +++ b/pkg/apis/k3s.cattle.io/v1/zz_generated_list_types.go @@ -40,3 +40,20 @@ func NewAddon(namespace, name string, obj Addon) *Addon { obj.Namespace = namespace return &obj } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ETCDSnapshotFileList is a list of ETCDSnapshotFile resources +type ETCDSnapshotFileList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ETCDSnapshotFile `json:"items"` +} + +func NewETCDSnapshotFile(namespace, name string, obj ETCDSnapshotFile) *ETCDSnapshotFile { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ETCDSnapshotFile").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/pkg/apis/k3s.cattle.io/v1/zz_generated_register.go b/pkg/apis/k3s.cattle.io/v1/zz_generated_register.go index 80e8f36298..90761711f7 100644 --- a/pkg/apis/k3s.cattle.io/v1/zz_generated_register.go +++ b/pkg/apis/k3s.cattle.io/v1/zz_generated_register.go @@ -28,7 +28,8 @@ import ( ) var ( - AddonResourceName = "addons" + AddonResourceName = "addons" + ETCDSnapshotFileResourceName = "etcdsnapshotfiles" ) // SchemeGroupVersion is group version used to register these objects @@ -54,6 +55,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Addon{}, &AddonList{}, + &ETCDSnapshotFile{}, + &ETCDSnapshotFileList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/codegen/main.go b/pkg/codegen/main.go index e9b6e370de..afb2d622ec 100644 --- a/pkg/codegen/main.go +++ b/pkg/codegen/main.go @@ -74,6 +74,7 @@ func main() { "k3s.cattle.io": { Types: []interface{}{ v1.Addon{}, + v1.ETCDSnapshotFile{}, }, GenerateTypes: true, GenerateClients: true, diff --git a/pkg/crd/crds.go b/pkg/crd/crds.go index 634f555087..0a1a918dbe 100644 --- a/pkg/crd/crds.go +++ b/pkg/crd/crds.go @@ -6,10 +6,19 @@ import ( ) func List() []crd.CRD { - addon := crd.NamespacedType("Addon.k3s.cattle.io/v1"). - WithSchemaFromStruct(v1.Addon{}). - WithColumn("Source", ".spec.source"). - WithColumn("Checksum", ".spec.checksum") - - return []crd.CRD{addon} + addon := v1.Addon{} + etcdSnapshotFile := v1.ETCDSnapshotFile{} + return []crd.CRD{ + crd.NamespacedType("Addon.k3s.cattle.io/v1"). + WithSchemaFromStruct(addon). + WithColumn("Source", ".spec.source"). + WithColumn("Checksum", ".spec.checksum"), + crd.NonNamespacedType("ETCDSnapshotFile.k3s.cattle.io/v1"). + WithSchemaFromStruct(etcdSnapshotFile). + WithColumn("SnapshotName", ".spec.snapshotName"). + WithColumn("Node", ".spec.nodeName"). + WithColumn("Location", ".spec.location"). + WithColumn("Size", ".status.size"). + WithColumn("CreationTime", ".status.creationTime"), + } } diff --git a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/etcdsnapshotfile.go b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/etcdsnapshotfile.go new file mode 100644 index 0000000000..148cd2af83 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/etcdsnapshotfile.go @@ -0,0 +1,184 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/k3s-io/k3s/pkg/apis/k3s.cattle.io/v1" + scheme "github.com/k3s-io/k3s/pkg/generated/clientset/versioned/scheme" + metav1 "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" +) + +// ETCDSnapshotFilesGetter has a method to return a ETCDSnapshotFileInterface. +// A group's client should implement this interface. +type ETCDSnapshotFilesGetter interface { + ETCDSnapshotFiles() ETCDSnapshotFileInterface +} + +// ETCDSnapshotFileInterface has methods to work with ETCDSnapshotFile resources. +type ETCDSnapshotFileInterface interface { + Create(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.CreateOptions) (*v1.ETCDSnapshotFile, error) + Update(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (*v1.ETCDSnapshotFile, error) + UpdateStatus(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (*v1.ETCDSnapshotFile, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ETCDSnapshotFile, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ETCDSnapshotFileList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshotFile, err error) + ETCDSnapshotFileExpansion +} + +// eTCDSnapshotFiles implements ETCDSnapshotFileInterface +type eTCDSnapshotFiles struct { + client rest.Interface +} + +// newETCDSnapshotFiles returns a ETCDSnapshotFiles +func newETCDSnapshotFiles(c *K3sV1Client) *eTCDSnapshotFiles { + return &eTCDSnapshotFiles{ + client: c.RESTClient(), + } +} + +// Get takes name of the eTCDSnapshotFile, and returns the corresponding eTCDSnapshotFile object, and an error if there is any. +func (c *eTCDSnapshotFiles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ETCDSnapshotFile, err error) { + result = &v1.ETCDSnapshotFile{} + err = c.client.Get(). + Resource("etcdsnapshotfiles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ETCDSnapshotFiles that match those selectors. +func (c *eTCDSnapshotFiles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ETCDSnapshotFileList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ETCDSnapshotFileList{} + err = c.client.Get(). + Resource("etcdsnapshotfiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested eTCDSnapshotFiles. +func (c *eTCDSnapshotFiles) Watch(ctx context.Context, opts metav1.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(). + Resource("etcdsnapshotfiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a eTCDSnapshotFile and creates it. Returns the server's representation of the eTCDSnapshotFile, and an error, if there is any. +func (c *eTCDSnapshotFiles) Create(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.CreateOptions) (result *v1.ETCDSnapshotFile, err error) { + result = &v1.ETCDSnapshotFile{} + err = c.client.Post(). + Resource("etcdsnapshotfiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshotFile). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a eTCDSnapshotFile and updates it. Returns the server's representation of the eTCDSnapshotFile, and an error, if there is any. +func (c *eTCDSnapshotFiles) Update(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (result *v1.ETCDSnapshotFile, err error) { + result = &v1.ETCDSnapshotFile{} + err = c.client.Put(). + Resource("etcdsnapshotfiles"). + Name(eTCDSnapshotFile.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshotFile). + 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 *eTCDSnapshotFiles) UpdateStatus(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (result *v1.ETCDSnapshotFile, err error) { + result = &v1.ETCDSnapshotFile{} + err = c.client.Put(). + Resource("etcdsnapshotfiles"). + Name(eTCDSnapshotFile.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshotFile). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the eTCDSnapshotFile and deletes it. Returns an error if one occurs. +func (c *eTCDSnapshotFiles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("etcdsnapshotfiles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *eTCDSnapshotFiles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("etcdsnapshotfiles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched eTCDSnapshotFile. +func (c *eTCDSnapshotFiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshotFile, err error) { + result = &v1.ETCDSnapshotFile{} + err = c.client.Patch(pt). + Resource("etcdsnapshotfiles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_etcdsnapshotfile.go b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_etcdsnapshotfile.go new file mode 100644 index 0000000000..b4ad567c34 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_etcdsnapshotfile.go @@ -0,0 +1,132 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/k3s-io/k3s/pkg/apis/k3s.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeETCDSnapshotFiles implements ETCDSnapshotFileInterface +type FakeETCDSnapshotFiles struct { + Fake *FakeK3sV1 +} + +var etcdsnapshotfilesResource = v1.SchemeGroupVersion.WithResource("etcdsnapshotfiles") + +var etcdsnapshotfilesKind = v1.SchemeGroupVersion.WithKind("ETCDSnapshotFile") + +// Get takes name of the eTCDSnapshotFile, and returns the corresponding eTCDSnapshotFile object, and an error if there is any. +func (c *FakeETCDSnapshotFiles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ETCDSnapshotFile, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(etcdsnapshotfilesResource, name), &v1.ETCDSnapshotFile{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshotFile), err +} + +// List takes label and field selectors, and returns the list of ETCDSnapshotFiles that match those selectors. +func (c *FakeETCDSnapshotFiles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ETCDSnapshotFileList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(etcdsnapshotfilesResource, etcdsnapshotfilesKind, opts), &v1.ETCDSnapshotFileList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ETCDSnapshotFileList{ListMeta: obj.(*v1.ETCDSnapshotFileList).ListMeta} + for _, item := range obj.(*v1.ETCDSnapshotFileList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested eTCDSnapshotFiles. +func (c *FakeETCDSnapshotFiles) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(etcdsnapshotfilesResource, opts)) +} + +// Create takes the representation of a eTCDSnapshotFile and creates it. Returns the server's representation of the eTCDSnapshotFile, and an error, if there is any. +func (c *FakeETCDSnapshotFiles) Create(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.CreateOptions) (result *v1.ETCDSnapshotFile, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(etcdsnapshotfilesResource, eTCDSnapshotFile), &v1.ETCDSnapshotFile{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshotFile), err +} + +// Update takes the representation of a eTCDSnapshotFile and updates it. Returns the server's representation of the eTCDSnapshotFile, and an error, if there is any. +func (c *FakeETCDSnapshotFiles) Update(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (result *v1.ETCDSnapshotFile, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(etcdsnapshotfilesResource, eTCDSnapshotFile), &v1.ETCDSnapshotFile{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshotFile), 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 *FakeETCDSnapshotFiles) UpdateStatus(ctx context.Context, eTCDSnapshotFile *v1.ETCDSnapshotFile, opts metav1.UpdateOptions) (*v1.ETCDSnapshotFile, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(etcdsnapshotfilesResource, "status", eTCDSnapshotFile), &v1.ETCDSnapshotFile{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshotFile), err +} + +// Delete takes name of the eTCDSnapshotFile and deletes it. Returns an error if one occurs. +func (c *FakeETCDSnapshotFiles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(etcdsnapshotfilesResource, name, opts), &v1.ETCDSnapshotFile{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeETCDSnapshotFiles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(etcdsnapshotfilesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ETCDSnapshotFileList{}) + return err +} + +// Patch applies the patch and returns the patched eTCDSnapshotFile. +func (c *FakeETCDSnapshotFiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshotFile, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(etcdsnapshotfilesResource, name, pt, data, subresources...), &v1.ETCDSnapshotFile{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshotFile), err +} diff --git a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_k3s.cattle.io_client.go b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_k3s.cattle.io_client.go index 562baa9638..7167f94bf9 100644 --- a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_k3s.cattle.io_client.go +++ b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/fake/fake_k3s.cattle.io_client.go @@ -32,6 +32,10 @@ func (c *FakeK3sV1) Addons(namespace string) v1.AddonInterface { return &FakeAddons{c, namespace} } +func (c *FakeK3sV1) ETCDSnapshotFiles() v1.ETCDSnapshotFileInterface { + return &FakeETCDSnapshotFiles{c} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeK3sV1) RESTClient() rest.Interface { diff --git a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/generated_expansion.go index 1b681d3f1f..d152245a29 100644 --- a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/generated_expansion.go @@ -19,3 +19,5 @@ limitations under the License. package v1 type AddonExpansion interface{} + +type ETCDSnapshotFileExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/k3s.cattle.io_client.go b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/k3s.cattle.io_client.go index a1e0d1fbaf..77bd599332 100644 --- a/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/k3s.cattle.io_client.go +++ b/pkg/generated/clientset/versioned/typed/k3s.cattle.io/v1/k3s.cattle.io_client.go @@ -29,6 +29,7 @@ import ( type K3sV1Interface interface { RESTClient() rest.Interface AddonsGetter + ETCDSnapshotFilesGetter } // K3sV1Client is used to interact with features provided by the k3s.cattle.io group. @@ -40,6 +41,10 @@ func (c *K3sV1Client) Addons(namespace string) AddonInterface { return newAddons(c, namespace) } +func (c *K3sV1Client) ETCDSnapshotFiles() ETCDSnapshotFileInterface { + return newETCDSnapshotFiles(c) +} + // NewForConfig creates a new K3sV1Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/pkg/generated/controllers/k3s.cattle.io/v1/etcdsnapshotfile.go b/pkg/generated/controllers/k3s.cattle.io/v1/etcdsnapshotfile.go new file mode 100644 index 0000000000..8358d1ae3b --- /dev/null +++ b/pkg/generated/controllers/k3s.cattle.io/v1/etcdsnapshotfile.go @@ -0,0 +1,161 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/k3s-io/k3s/pkg/apis/k3s.cattle.io/v1" + "github.com/rancher/wrangler/pkg/apply" + "github.com/rancher/wrangler/pkg/condition" + "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ETCDSnapshotFileController interface for managing ETCDSnapshotFile resources. +type ETCDSnapshotFileController interface { + generic.NonNamespacedControllerInterface[*v1.ETCDSnapshotFile, *v1.ETCDSnapshotFileList] +} + +// ETCDSnapshotFileClient interface for managing ETCDSnapshotFile resources in Kubernetes. +type ETCDSnapshotFileClient interface { + generic.NonNamespacedClientInterface[*v1.ETCDSnapshotFile, *v1.ETCDSnapshotFileList] +} + +// ETCDSnapshotFileCache interface for retrieving ETCDSnapshotFile resources in memory. +type ETCDSnapshotFileCache interface { + generic.NonNamespacedCacheInterface[*v1.ETCDSnapshotFile] +} + +type ETCDSnapshotFileStatusHandler func(obj *v1.ETCDSnapshotFile, status v1.ETCDSnapshotStatus) (v1.ETCDSnapshotStatus, error) + +type ETCDSnapshotFileGeneratingHandler func(obj *v1.ETCDSnapshotFile, status v1.ETCDSnapshotStatus) ([]runtime.Object, v1.ETCDSnapshotStatus, error) + +func RegisterETCDSnapshotFileStatusHandler(ctx context.Context, controller ETCDSnapshotFileController, condition condition.Cond, name string, handler ETCDSnapshotFileStatusHandler) { + statusHandler := &eTCDSnapshotFileStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +func RegisterETCDSnapshotFileGeneratingHandler(ctx context.Context, controller ETCDSnapshotFileController, apply apply.Apply, + condition condition.Cond, name string, handler ETCDSnapshotFileGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &eTCDSnapshotFileGeneratingHandler{ + ETCDSnapshotFileGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterETCDSnapshotFileStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type eTCDSnapshotFileStatusHandler struct { + client ETCDSnapshotFileClient + condition condition.Cond + handler ETCDSnapshotFileStatusHandler +} + +func (a *eTCDSnapshotFileStatusHandler) sync(key string, obj *v1.ETCDSnapshotFile) (*v1.ETCDSnapshotFile, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type eTCDSnapshotFileGeneratingHandler struct { + ETCDSnapshotFileGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string +} + +func (a *eTCDSnapshotFileGeneratingHandler) Remove(key string, obj *v1.ETCDSnapshotFile) (*v1.ETCDSnapshotFile, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.ETCDSnapshotFile{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +func (a *eTCDSnapshotFileGeneratingHandler) Handle(obj *v1.ETCDSnapshotFile, status v1.ETCDSnapshotStatus) (v1.ETCDSnapshotStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ETCDSnapshotFileGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) +} diff --git a/pkg/generated/controllers/k3s.cattle.io/v1/interface.go b/pkg/generated/controllers/k3s.cattle.io/v1/interface.go index 656a013c2f..6a80c591ac 100644 --- a/pkg/generated/controllers/k3s.cattle.io/v1/interface.go +++ b/pkg/generated/controllers/k3s.cattle.io/v1/interface.go @@ -32,6 +32,7 @@ func init() { type Interface interface { Addon() AddonController + ETCDSnapshotFile() ETCDSnapshotFileController } func New(controllerFactory controller.SharedControllerFactory) Interface { @@ -47,3 +48,7 @@ type version struct { func (v *version) Addon() AddonController { return generic.NewController[*v1.Addon, *v1.AddonList](schema.GroupVersionKind{Group: "k3s.cattle.io", Version: "v1", Kind: "Addon"}, "addons", true, v.controllerFactory) } + +func (v *version) ETCDSnapshotFile() ETCDSnapshotFileController { + return generic.NewNonNamespacedController[*v1.ETCDSnapshotFile, *v1.ETCDSnapshotFileList](schema.GroupVersionKind{Group: "k3s.cattle.io", Version: "v1", Kind: "ETCDSnapshotFile"}, "etcdsnapshotfiles", v.controllerFactory) +}