From a9abbe90f8c5ea61d9bf319f3271660e73b28ddd Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Fri, 13 May 2022 18:55:44 +0200 Subject: [PATCH] RuntimeSDK: Add types for Topology Mutation Hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Büringer buringerst@vmware.com --- .../api/v1alpha1/topologymutation_types.go | 190 ++++++++++++++ .../api/v1alpha1/zz_generated.deepcopy.go | 236 +++++++++++++++++- 2 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 exp/runtime/hooks/api/v1alpha1/topologymutation_types.go diff --git a/exp/runtime/hooks/api/v1alpha1/topologymutation_types.go b/exp/runtime/hooks/api/v1alpha1/topologymutation_types.go new file mode 100644 index 000000000000..07d004e2957b --- /dev/null +++ b/exp/runtime/hooks/api/v1alpha1/topologymutation_types.go @@ -0,0 +1,190 @@ +/* +Copyright 2022 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. +*/ + +package v1alpha1 + +import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + + "sigs.k8s.io/cluster-api/internal/runtime/catalog" +) + +// GeneratePatchesRequest is the request of the GeneratePatches hook. +// +kubebuilder:object:root=true +type GeneratePatchesRequest struct { + metav1.TypeMeta `json:",inline"` + + // Variables are global variables for all templates. + Variables []Variable `json:"variables"` + + // Items is the list of templates to generate patches for. + Items []GeneratePatchesRequestItem `json:"items"` +} + +// GeneratePatchesRequestItem represents a template to generate patches for. +type GeneratePatchesRequestItem struct { + // UID is an identifier for this template. It allows us to correlate the template in the request + // with the corresponding generates patches in the response. + UID types.UID `json:"uid"` + + // HolderReference is a reference to the object where the template is used. + HolderReference HolderReference `json:"holderReference"` + + // Object contains the template as a raw object. + Object runtime.RawExtension `json:"object"` + + // Variables are variables specific for the current template. + // For example some builtin variables like MachineDeployment replicas and version are context-sensitive + // and thus are only added to templates for MachineDeployments and with values which correspond to the + // current MachineDeployment. + Variables []Variable `json:"variables"` +} + +// GeneratePatchesResponse is the response of the GeneratePatches hook. +// NOTE: The patches in GeneratePatchesResponse will be applied in the order in which they are defined to the +// templates of the request. Thus applying changes consecutively when iterating through internal and external patches. +// +kubebuilder:object:root=true +type GeneratePatchesResponse struct { + metav1.TypeMeta `json:",inline"` + + // Status of the call. + // One of: "Success" or "Failure". + Status ResponseStatus `json:"status"` + + // A human-readable description of the status of the call. + Message string `json:"message,omitempty"` + + // Items is the list of generated patches. + Items []GeneratePatchesResponseItem `json:"items"` +} + +// GeneratePatchesResponseItem is a generated patch. +type GeneratePatchesResponseItem struct { + // UID identifies the corresponding template in the request on which + // the patch should be applied. + UID types.UID `json:"uid"` + + // PatchType defines the type of the patch. + // One of: "JSONPatch" or "JSONMergePatch". + PatchType PatchType `json:"patchType"` + + // Patch contains the patch which should be applied to the template. + // It must be of the corresponding PatchType. + Patch []byte `json:"patch"` +} + +// PatchType defines the supported patch types. +// +enum +type PatchType string + +const ( + // JSONPatchType identifies a https://datatracker.ietf.org/doc/html/rfc6902 JSON patch. + JSONPatchType PatchType = "JSONPatch" + + // JSONMergePatchType identifies a https://datatracker.ietf.org/doc/html/rfc7386 JSON merge patch. + JSONMergePatchType PatchType = "JSONMergePatch" +) + +func GeneratePatches(*GeneratePatchesRequest, *GeneratePatchesResponse) {} + +// ValidateTopologyRequest is the request of the ValidateTopology hook. +// +kubebuilder:object:root=true +type ValidateTopologyRequest struct { + metav1.TypeMeta `json:",inline"` + + // Variables are global variables for all templates. + Variables []Variable `json:"variables"` + + // Items is the list of templates to validate. + Items []*ValidateTopologyRequestItem `json:"items"` +} + +// ValidateTopologyRequestItem represents a template to validate. +type ValidateTopologyRequestItem struct { + // HolderReference is a reference to the object where the template is used. + HolderReference HolderReference `json:"holderReference"` + + // Object contains the template as a raw object. + Object runtime.RawExtension `json:"object"` + + // Variables are variables specific for the current template. + // For example some builtin variables like MachineDeployment replicas and version are context-sensitive + // and thus are only added to templates for MachineDeployments and with values which correspond to the + // current MachineDeployment. + Variables []Variable `json:"variables"` +} + +// ValidateTopologyResponse is the response of the ValidateTopology hook. +// +kubebuilder:object:root=true +type ValidateTopologyResponse struct { + metav1.TypeMeta `json:",inline"` + + // Status of the call. + // One of: "Success" or "Failure". + Status ResponseStatus `json:"status"` + + // A human-readable description of the status of the call. + Message string `json:"message"` +} + +// Variable represents a variable value. +type Variable struct { + // Name of the variable. + Name string `json:"name"` + + // Value of the variable. + Value apiextensionsv1.JSON `json:"value"` +} + +// HolderReference represents a reference to an object which holds a template. +type HolderReference struct { + // API version of the referent. + APIVersion string `json:"apiVersion"` + + // Kind of the referent. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + Kind string `json:"kind"` + + // Namespace of the referent. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + Namespace string `json:"namespace"` + + // Name of the referent. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Name string `json:"name"` + + // FieldPath is the path to the field of the object which references the template. + FieldPath string `json:"fieldPath"` +} + +func ValidateTopology(*GeneratePatchesRequest, *GeneratePatchesResponse) {} + +func init() { + catalogBuilder.RegisterHook(GeneratePatches, &catalog.HookMeta{ + Tags: []string{"Topology Mutation Hook"}, + Summary: "GeneratePatches generates patches during topology reconciliation for the entire Cluster topology.", + Description: "A GeneratePatches call generates patches for the entire Cluster topology. Accordingly the request contains all templates, the global variables and the template-specific variables. The response contains generated patches.", + }) + + catalogBuilder.RegisterHook(ValidateTopology, &catalog.HookMeta{ + Tags: []string{"Topology Mutation Hook"}, + Summary: "ValidateTopology validates the Cluster topology after all patches have been applied.", + Description: "A ValidateTopology call validates the Cluster topology after all patches have been applied. The request contains all templates of the Cluster topology, the global variables and the template-specific variables. The response contains the result of the validation.", + }) +} diff --git a/exp/runtime/hooks/api/v1alpha1/zz_generated.deepcopy.go b/exp/runtime/hooks/api/v1alpha1/zz_generated.deepcopy.go index 8d820b3694a3..14f481edb56d 100644 --- a/exp/runtime/hooks/api/v1alpha1/zz_generated.deepcopy.go +++ b/exp/runtime/hooks/api/v1alpha1/zz_generated.deepcopy.go @@ -22,7 +22,7 @@ limitations under the License. package v1alpha1 import ( - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -106,6 +106,119 @@ func (in *ExtensionHandler) DeepCopy() *ExtensionHandler { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GeneratePatchesRequest) DeepCopyInto(out *GeneratePatchesRequest) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GeneratePatchesRequestItem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratePatchesRequest. +func (in *GeneratePatchesRequest) DeepCopy() *GeneratePatchesRequest { + if in == nil { + return nil + } + out := new(GeneratePatchesRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GeneratePatchesRequest) 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 *GeneratePatchesRequestItem) DeepCopyInto(out *GeneratePatchesRequestItem) { + *out = *in + out.HolderReference = in.HolderReference + in.Object.DeepCopyInto(&out.Object) + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratePatchesRequestItem. +func (in *GeneratePatchesRequestItem) DeepCopy() *GeneratePatchesRequestItem { + if in == nil { + return nil + } + out := new(GeneratePatchesRequestItem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GeneratePatchesResponse) DeepCopyInto(out *GeneratePatchesResponse) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GeneratePatchesResponseItem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratePatchesResponse. +func (in *GeneratePatchesResponse) DeepCopy() *GeneratePatchesResponse { + if in == nil { + return nil + } + out := new(GeneratePatchesResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GeneratePatchesResponse) 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 *GeneratePatchesResponseItem) DeepCopyInto(out *GeneratePatchesResponseItem) { + *out = *in + if in.Patch != nil { + in, out := &in.Patch, &out.Patch + *out = make([]byte, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratePatchesResponseItem. +func (in *GeneratePatchesResponseItem) DeepCopy() *GeneratePatchesResponseItem { + if in == nil { + return nil + } + out := new(GeneratePatchesResponseItem) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GroupVersionHook) DeepCopyInto(out *GroupVersionHook) { *out = *in @@ -120,3 +233,124 @@ func (in *GroupVersionHook) DeepCopy() *GroupVersionHook { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HolderReference) DeepCopyInto(out *HolderReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HolderReference. +func (in *HolderReference) DeepCopy() *HolderReference { + if in == nil { + return nil + } + out := new(HolderReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidateTopologyRequest) DeepCopyInto(out *ValidateTopologyRequest) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]*ValidateTopologyRequestItem, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ValidateTopologyRequestItem) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidateTopologyRequest. +func (in *ValidateTopologyRequest) DeepCopy() *ValidateTopologyRequest { + if in == nil { + return nil + } + out := new(ValidateTopologyRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidateTopologyRequest) 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 *ValidateTopologyRequestItem) DeepCopyInto(out *ValidateTopologyRequestItem) { + *out = *in + out.HolderReference = in.HolderReference + in.Object.DeepCopyInto(&out.Object) + if in.Variables != nil { + in, out := &in.Variables, &out.Variables + *out = make([]Variable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidateTopologyRequestItem. +func (in *ValidateTopologyRequestItem) DeepCopy() *ValidateTopologyRequestItem { + if in == nil { + return nil + } + out := new(ValidateTopologyRequestItem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidateTopologyResponse) DeepCopyInto(out *ValidateTopologyResponse) { + *out = *in + out.TypeMeta = in.TypeMeta +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValidateTopologyResponse. +func (in *ValidateTopologyResponse) DeepCopy() *ValidateTopologyResponse { + if in == nil { + return nil + } + out := new(ValidateTopologyResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ValidateTopologyResponse) 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 *Variable) DeepCopyInto(out *Variable) { + *out = *in + in.Value.DeepCopyInto(&out.Value) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Variable. +func (in *Variable) DeepCopy() *Variable { + if in == nil { + return nil + } + out := new(Variable) + in.DeepCopyInto(out) + return out +}