diff --git a/Makefile b/Makefile index cf4253a..102eb66 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,8 @@ CRD_OPTIONS ?= "crd:Versions=v1" .PHONY: generate generate: ## Runs code generation tooling - $(MAKE) generate-api + $(MAKE) generate-go + $(MAKE) generate-manifests generate-go: $(CONTROLLER_GEN) $(DEFAULTER_GEN) $(CONTROLLER_GEN) \ diff --git a/PROJECT b/PROJECT index 9ffd0ae..9c2d1ac 100644 --- a/PROJECT +++ b/PROJECT @@ -22,4 +22,13 @@ resources: kind: MicrovmMachine path: github.com/weaveworks/cluster-api-provider-microvm/api/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: false + domain: cluster.x-k8s.io + group: infrastructure + kind: MicrovmMachineTemplate + path: github.com/weaveworks/cluster-api-provider-microvm/api/v1alpha1 + version: v1alpha1 version: "3" diff --git a/api/v1alpha1/microvmcluster_types.go b/api/v1alpha1/microvmcluster_types.go index 1ee8f46..b2391b3 100644 --- a/api/v1alpha1/microvmcluster_types.go +++ b/api/v1alpha1/microvmcluster_types.go @@ -5,19 +5,46 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + // ClusterFinalizer allows ReconcileMicrovmCluster to clean up esources associated with MicrovmCluster before + // removing it from the apiserver. + ClusterFinalizer = "microvmcluster.infrastructure.cluster.x-k8s.io" ) // MicrovmClusterSpec defines the desired state of MicrovmCluster. type MicrovmClusterSpec struct { - // Foo is an example field of MicrovmCluster. Edit microvmcluster_types.go to remove/update - Foo string `json:"foo,omitempty"` + // ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + // + // See https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html + // for more details. + // + // +optional + ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"` } // MicrovmClusterStatus defines the observed state of MicrovmCluster. -type MicrovmClusterStatus struct{} +type MicrovmClusterStatus struct { + // Ready indicates that the cluster is ready. + // +optional + // +kubebuilder:default=false + Ready bool `json:"ready"` -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status + // Conditions defines current service state of the MicrovmCluster. + // +optional + Conditions clusterv1.Conditions `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:path=microvmclusters,scope=Namespaced,categories=cluster-api,shortName=mvmc +// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this MicrovmCluster belongs" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Cluster infrastructure is ready" +// +kubebuilder:printcolumn:name="ControlPlaneEndpoint",type="string",JSONPath=".spec.controlPlaneEndpoint[0]",description="API Endpoint",priority=1 +// +k8s:defaulter-gen=true // MicrovmCluster is the Schema for the microvmclusters API. type MicrovmCluster struct { @@ -28,9 +55,20 @@ type MicrovmCluster struct { Status MicrovmClusterStatus `json:"status,omitempty"` } +// GetConditions returns the observations of the operational state of the MicrovmCluster resource. +func (r *MicrovmCluster) GetConditions() clusterv1.Conditions { + return r.Status.Conditions +} + +// SetConditions sets the underlying service state of the MicrovmCluster to the predescribed clusterv1.Conditions. +func (r *MicrovmCluster) SetConditions(conditions clusterv1.Conditions) { + r.Status.Conditions = conditions +} + //+kubebuilder:object:root=true // MicrovmClusterList contains a list of MicrovmCluster. +// +k8s:defaulter-gen=true type MicrovmClusterList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` diff --git a/api/v1alpha1/microvmmachine_types.go b/api/v1alpha1/microvmmachine_types.go index 03a4fea..94282ac 100644 --- a/api/v1alpha1/microvmmachine_types.go +++ b/api/v1alpha1/microvmmachine_types.go @@ -5,16 +5,79 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/errors" +) + +const ( + // MachineFinalizer allows ReconcileMicrovmMachine to clean up resources associated with MicrovmMachine + // before removing it from the apiserver. + MachineFinalizer = "microvmmachine.infrastructure.cluster.x-k8s.io" ) // MicrovmMachineSpec defines the desired state of MicrovmMachine. type MicrovmMachineSpec struct { - // Foo is an example field of MicrovmMachine. Edit microvmmachine_types.go to remove/update - Foo string `json:"foo,omitempty"` + MicrovmSpec `json:",inline"` + + // ProviderID is the unique identifier as specified by the cloud provider. + ProviderID *string `json:"providerID,omitempty"` } // MicrovmMachineStatus defines the observed state of MicrovmMachine. -type MicrovmMachineStatus struct{} +type MicrovmMachineStatus struct { + // Ready is true when the provider resource is ready. + // +optional + // +kubebuilder:default=false + Ready bool `json:"ready"` + + // VMState indicates the state of the microvm. + VMState *VMState `json:"vmState,omitempty"` + + // Addresses contains the microvm associated addresses. + Addresses []clusterv1.MachineAddress `json:"addresses,omitempty"` + + // FailureReason will be set in the event that there is a terminal problem + // reconciling the Machine and will contain a succinct value suitable + // for machine interpretation. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the Machine's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the Machine object and/or logged in the + // controller's output. + // +optional + FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"` + + // FailureMessage will be set in the event that there is a terminal problem + // reconciling the Machine and will contain a more verbose string suitable + // for logging and human consumption. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the Machine's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the Machine object and/or logged in the + // controller's output. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + // Conditions defines current service state of the MicrovmMachine. + // +optional + Conditions clusterv1.Conditions `json:"conditions,omitempty"` +} //+kubebuilder:object:root=true //+kubebuilder:subresource:status diff --git a/api/v1alpha1/microvmmachine_webhook.go b/api/v1alpha1/microvmmachine_webhook.go index ce08385..994cd9b 100644 --- a/api/v1alpha1/microvmmachine_webhook.go +++ b/api/v1alpha1/microvmmachine_webhook.go @@ -4,7 +4,10 @@ package v1alpha1 import ( + "reflect" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -38,7 +41,15 @@ func (r *MicrovmMachine) ValidateDelete() error { // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. func (r *MicrovmMachine) ValidateUpdate(old runtime.Object) error { - return nil + var allErrs field.ErrorList + + previous, _ := old.(*MicrovmMachine) + + if !reflect.DeepEqual(r.Spec, previous.Spec) { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "microvm machine spec is immutable")) + } + + return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) } // Default satisfies the defaulting webhook interface. diff --git a/api/v1alpha1/microvmmachinetemplate_types.go b/api/v1alpha1/microvmmachinetemplate_types.go new file mode 100644 index 0000000..f197745 --- /dev/null +++ b/api/v1alpha1/microvmmachinetemplate_types.go @@ -0,0 +1,39 @@ +// Copyright 2021 Weaveworks or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MPL-2.0 + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// MicrovmMachineTemplateSpec defines the desired state of MicrovmMachineTemplate. +type MicrovmMachineTemplateSpec struct { + Template MicrovmMachineTemplateResource `json:"template"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:resource:path=microvmmachinetemplates,scope=Namespaced,categories=cluster-api,shortName=mvmmt +// +k8s:defaulter-gen=true + +// MicrovmMachineTemplate is the Schema for the microvmmachinetemplates API. +type MicrovmMachineTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec MicrovmMachineTemplateSpec `json:"spec,omitempty"` +} + +//+kubebuilder:object:root=true + +// MicrovmMachineTemplateList contains a list of MicrovmMachineTemplate. +type MicrovmMachineTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MicrovmMachineTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MicrovmMachineTemplate{}, &MicrovmMachineTemplateList{}) +} diff --git a/api/v1alpha1/microvmmachinetemplate_webhook.go b/api/v1alpha1/microvmmachinetemplate_webhook.go new file mode 100644 index 0000000..df59960 --- /dev/null +++ b/api/v1alpha1/microvmmachinetemplate_webhook.go @@ -0,0 +1,38 @@ +// Copyright 2021 Weaveworks or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MPL-2.0 + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var _ = logf.Log.WithName("microvmmachinetemplate-resource") + +func (r *MicrovmMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha1-microvmmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=microvmmachinetemplates,versions=v1alpha1,name=validation.microvmmachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 + +var _ webhook.Validator = &MicrovmMachineTemplate{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. +func (r *MicrovmMachineTemplate) ValidateCreate() error { + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. +func (r *MicrovmMachineTemplate) ValidateDelete() error { + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. +func (r *MicrovmMachineTemplate) ValidateUpdate(old runtime.Object) error { + return nil +} diff --git a/api/v1alpha1/types.go b/api/v1alpha1/types.go new file mode 100644 index 0000000..6c8f21c --- /dev/null +++ b/api/v1alpha1/types.go @@ -0,0 +1,119 @@ +// Copyright 2021 Weaveworks or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MPL-2.0 + +package v1alpha1 + +import ( + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// MicrovmSpec represents the specification for a microvm +type MicrovmSpec struct { + // VCPU specifies how many vcpu's the microvm will be allocated. + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum:=1 + VCPU int64 `json:"vcpu"` + + // MemoryMb is the amount of memory in megabytes that the microvm will be allocated. + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum:=1024 + MemoryMb int64 `json:"memoryMb"` + + // RootVolume specifies the volume to use for the root of the microvm. + // +kubebuilder:validation:Required + RootVolume Volume `json:"rootVolume"` + + // AdditionalVolumes specifies additional non-root volumes to attach to the microvm. + // +optional + AdditionalVolumes []Volume `json:"volumes,omitempty"` + + // Kernel specifies the kernel and its arguments to use. + // +kubebuilder:validation:Required + Kernel ContainerFileSource `json:"kernel"` + + // KernelCmdLine are the args to use for the kernel cmdline. + // +kubebuilder:validation:MinLength:=5 + // +kubebuilder:default:=console=ttyS0 reboot=k panic=1 pci=off i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd + KernelCmdLine string `json:"kernelCmdline,omitempty"` + + // Initrd is an optional initial ramdisk to use. + // +optional + Initrd *ContainerFileSource `json:"initrd,omitempty"` + + // NetworkInterfaces specifies the network interfaces attached to the microvm. + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems:=1 + NetworkInterfaces []NetworkInterface `json:"networkInterfaces"` +} + +// MicrovmMachineTemplateResource describes the data needed to create a MicrovmMachine from a template. +type MicrovmMachineTemplateResource struct { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + ObjectMeta clusterv1.ObjectMeta `json:"metadata,omitempty"` + + // Spec is the specification of the machine. + Spec MicrovmMachineSpec `json:"spec"` +} + +// ContainerFileSource represents a file coming from a container. +type ContainerFileSource struct { + // Image is the container image to use. + // +kubebuilder:validation:Required + Image string `json:"image"` + // Filename is the name of the file in the container to use. + // +optional + Filename string `json:"filename,omitempty"` +} + +// Volume represents a volume to be attached to a microvm. +type Volume struct { + // Image is the container image to use for the volume. + // +kubebuilder:validation:Required + Image string `json:"image"` + // ReadOnly specifies that the volume is to be mounted readonly. + // +optional + ReadOnly bool `json:"readOnly,omitempty"` +} + +// IfaceType is a type representing the network interface types. +type IfaceType string + +const ( + // IfaceTypeTap is a TAP network interface. + IfaceTypeTap = "tap" + // IfaceTypeMacvtap is a MACVTAP network interface. + IfaceTypeMacvtap = "macvtap" +) + +// NetworkInterface represents a network interface for the microvm. +type NetworkInterface struct { + // GuestDeviceName is the name of the network interface to create in the microvm. + // +kubebuilder:validation:Required + GuestDeviceName string `json:"guestDeviceName"` + // GuestMAC allows the specifying of a specific MAC address to use for the interface. If + // not supplied a autogenerated MAC address will be used. + // +optional + GuestMAC string `json:"guestMac,omitempty"` + // Type is the type of host network interface type to create to use by the guest. + // +kubebuilder:validation:Enum=macvtap;tap + Type IfaceType `json:"type"` + // Address is an optional IP address to assign to this interface. If not supplied then DHCP will be used. + // +optional + Address string `json:"address,omitempty"` +} + +// VMState is a type that represents the state of a microvm. +type VMState string + +var ( + // VMStatePending indicates the microvm hasn't been started. + VMStatePending = "pending" + // VMStateRunning indicates the microvm is running. + VMStateRunning = "running" + // VMStateFailed indicates the microvm has failed. + VMStateFailed = "failed" + // VMStateDeleted indicates the microvm has been deleted. + VMStateDeleted = "deleted" +) diff --git a/api/v1alpha1/webhooks.go b/api/v1alpha1/webhooks.go new file mode 100644 index 0000000..f841d95 --- /dev/null +++ b/api/v1alpha1/webhooks.go @@ -0,0 +1,22 @@ +// Copyright 2021 Weaveworks or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MPL-2.0 + +package v1alpha1 + +import ( + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func aggregateObjErrors(gk schema.GroupKind, name string, allErrs field.ErrorList) error { + if len(allErrs) == 0 { + return nil + } + + return apierrors.NewInvalid( + gk, + name, + allErrs, + ) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6c4fe72..4406302 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -10,15 +10,32 @@ package v1alpha1 import ( "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/errors" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerFileSource) DeepCopyInto(out *ContainerFileSource) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerFileSource. +func (in *ContainerFileSource) DeepCopy() *ContainerFileSource { + if in == nil { + return nil + } + out := new(ContainerFileSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MicrovmCluster) DeepCopyInto(out *MicrovmCluster) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) out.Spec = in.Spec - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmCluster. @@ -74,6 +91,7 @@ func (in *MicrovmClusterList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MicrovmClusterSpec) DeepCopyInto(out *MicrovmClusterSpec) { *out = *in + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmClusterSpec. @@ -89,6 +107,13 @@ func (in *MicrovmClusterSpec) DeepCopy() *MicrovmClusterSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MicrovmClusterStatus) DeepCopyInto(out *MicrovmClusterStatus) { *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(v1beta1.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmClusterStatus. @@ -106,8 +131,8 @@ func (in *MicrovmMachine) DeepCopyInto(out *MicrovmMachine) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachine. @@ -163,6 +188,12 @@ func (in *MicrovmMachineList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MicrovmMachineSpec) DeepCopyInto(out *MicrovmMachineSpec) { *out = *in + in.MicrovmSpec.DeepCopyInto(&out.MicrovmSpec) + if in.ProviderID != nil { + in, out := &in.ProviderID, &out.ProviderID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineSpec. @@ -178,6 +209,33 @@ func (in *MicrovmMachineSpec) DeepCopy() *MicrovmMachineSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MicrovmMachineStatus) DeepCopyInto(out *MicrovmMachineStatus) { *out = *in + if in.VMState != nil { + in, out := &in.VMState, &out.VMState + *out = new(VMState) + **out = **in + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]v1beta1.MachineAddress, len(*in)) + copy(*out, *in) + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachineStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(v1beta1.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineStatus. @@ -189,3 +247,156 @@ func (in *MicrovmMachineStatus) DeepCopy() *MicrovmMachineStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MicrovmMachineTemplate) DeepCopyInto(out *MicrovmMachineTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineTemplate. +func (in *MicrovmMachineTemplate) DeepCopy() *MicrovmMachineTemplate { + if in == nil { + return nil + } + out := new(MicrovmMachineTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MicrovmMachineTemplate) 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 *MicrovmMachineTemplateList) DeepCopyInto(out *MicrovmMachineTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MicrovmMachineTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineTemplateList. +func (in *MicrovmMachineTemplateList) DeepCopy() *MicrovmMachineTemplateList { + if in == nil { + return nil + } + out := new(MicrovmMachineTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MicrovmMachineTemplateList) 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 *MicrovmMachineTemplateResource) DeepCopyInto(out *MicrovmMachineTemplateResource) { + *out = *in + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineTemplateResource. +func (in *MicrovmMachineTemplateResource) DeepCopy() *MicrovmMachineTemplateResource { + if in == nil { + return nil + } + out := new(MicrovmMachineTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MicrovmMachineTemplateSpec) DeepCopyInto(out *MicrovmMachineTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmMachineTemplateSpec. +func (in *MicrovmMachineTemplateSpec) DeepCopy() *MicrovmMachineTemplateSpec { + if in == nil { + return nil + } + out := new(MicrovmMachineTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MicrovmSpec) DeepCopyInto(out *MicrovmSpec) { + *out = *in + out.RootVolume = in.RootVolume + if in.AdditionalVolumes != nil { + in, out := &in.AdditionalVolumes, &out.AdditionalVolumes + *out = make([]Volume, len(*in)) + copy(*out, *in) + } + out.Kernel = in.Kernel + if in.Initrd != nil { + in, out := &in.Initrd, &out.Initrd + *out = new(ContainerFileSource) + **out = **in + } + if in.NetworkInterfaces != nil { + in, out := &in.NetworkInterfaces, &out.NetworkInterfaces + *out = make([]NetworkInterface, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrovmSpec. +func (in *MicrovmSpec) DeepCopy() *MicrovmSpec { + if in == nil { + return nil + } + out := new(MicrovmSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkInterface) DeepCopyInto(out *NetworkInterface) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkInterface. +func (in *NetworkInterface) DeepCopy() *NetworkInterface { + if in == nil { + return nil + } + out := new(NetworkInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Volume) DeepCopyInto(out *Volume) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Volume. +func (in *Volume) DeepCopy() *Volume { + if in == nil { + return nil + } + out := new(Volume) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmclusters.yaml index 634636c..fb073ad 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmclusters.yaml @@ -10,13 +10,31 @@ metadata: spec: group: infrastructure.cluster.x-k8s.io names: + categories: + - cluster-api kind: MicrovmCluster listKind: MicrovmClusterList plural: microvmclusters + shortNames: + - mvmc singular: microvmcluster scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - description: Cluster to which this MicrovmCluster belongs + jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name + name: Cluster + type: string + - description: Cluster infrastructure is ready + jsonPath: .status.ready + name: Ready + type: string + - description: API Endpoint + jsonPath: .spec.controlPlaneEndpoint[0] + name: ControlPlaneEndpoint + priority: 1 + type: string + name: v1alpha1 schema: openAPIV3Schema: description: MicrovmCluster is the Schema for the microvmclusters API. @@ -36,13 +54,75 @@ spec: spec: description: MicrovmClusterSpec defines the desired state of MicrovmCluster. properties: - foo: - description: Foo is an example field of MicrovmCluster. Edit microvmcluster_types.go - to remove/update - type: string + controlPlaneEndpoint: + description: "ControlPlaneEndpoint represents the endpoint used to + communicate with the control plane. \n See https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html + for more details." + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object type: object status: description: MicrovmClusterStatus defines the observed state of MicrovmCluster. + properties: + conditions: + description: Conditions defines current service state of the MicrovmCluster. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + ready: + default: false + description: Ready indicates that the cluster is ready. + type: boolean type: object type: object served: true diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachines.yaml index 0a42e46..142d9f1 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachines.yaml @@ -36,13 +36,227 @@ spec: spec: description: MicrovmMachineSpec defines the desired state of MicrovmMachine. properties: - foo: - description: Foo is an example field of MicrovmMachine. Edit microvmmachine_types.go - to remove/update + initrd: + description: Initrd is an optional initial ramdisk to use. + properties: + filename: + description: Filename is the name of the file in the container + to use. + type: string + image: + description: Image is the container image to use. + type: string + required: + - image + type: object + kernel: + description: Kernel specifies the kernel and its arguments to use. + properties: + filename: + description: Filename is the name of the file in the container + to use. + type: string + image: + description: Image is the container image to use. + type: string + required: + - image + type: object + kernelCmdline: + default: console=ttyS0 reboot=k panic=1 pci=off i8042.noaux i8042.nomux + i8042.nopnp i8042.dumbkbd + description: KernelCmdLine are the args to use for the kernel cmdline. + minLength: 5 type: string + memoryMb: + description: MemoryMb is the amount of memory in megabytes that the + microvm will be allocated. + format: int64 + minimum: 1024 + type: integer + networkInterfaces: + description: NetworkInterfaces specifies the network interfaces attached + to the microvm. + items: + description: NetworkInterface represents a network interface for + the microvm. + properties: + address: + description: Address is an optional IP address to assign to + this interface. If not supplied then DHCP will be used. + type: string + guestDeviceName: + description: GuestDeviceName is the name of the network interface + to create in the microvm. + type: string + guestMac: + description: GuestMAC allows the specifying of a specific MAC + address to use for the interface. If not supplied a autogenerated + MAC address will be used. + type: string + type: + description: Type is the type of host network interface type + to create to use by the guest. + enum: + - macvtap + - tap + type: string + required: + - guestDeviceName + - type + type: object + minItems: 1 + type: array + providerID: + description: ProviderID is the unique identifier as specified by the + cloud provider. + type: string + rootVolume: + description: RootVolume specifies the volume to use for the root of + the microvm. + properties: + image: + description: Image is the container image to use for the volume. + type: string + readOnly: + description: ReadOnly specifies that the volume is to be mounted + readonly. + type: boolean + required: + - image + type: object + vcpu: + description: VCPU specifies how many vcpu's the microvm will be allocated. + format: int64 + minimum: 1 + type: integer + volumes: + description: AdditionalVolumes specifies additional non-root volumes + to attach to the microvm. + items: + description: Volume represents a volume to be attached to a microvm. + properties: + image: + description: Image is the container image to use for the volume. + type: string + readOnly: + description: ReadOnly specifies that the volume is to be mounted + readonly. + type: boolean + required: + - image + type: object + type: array + required: + - kernel + - memoryMb + - networkInterfaces + - rootVolume + - vcpu type: object status: description: MicrovmMachineStatus defines the observed state of MicrovmMachine. + properties: + addresses: + description: Addresses contains the microvm associated addresses. + items: + description: MachineAddress contains information for the node's + address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP + or InternalIP. + type: string + required: + - address + - type + type: object + type: array + conditions: + description: Conditions defines current service state of the MicrovmMachine. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + description: "FailureMessage will be set in the event that there is + a terminal problem reconciling the Machine and will contain a more + verbose string suitable for logging and human consumption. \n This + field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over time (like + service outages), but instead indicate that something is fundamentally + wrong with the Machine's spec or the configuration of the controller, + and that manual intervention is required. Examples of terminal errors + would be invalid combinations of settings in the spec, values that + are unsupported by the controller, or the responsible controller + itself being critically misconfigured. \n Any transient errors that + occur during the reconciliation of Machines can be added as events + to the Machine object and/or logged in the controller's output." + type: string + failureReason: + description: "FailureReason will be set in the event that there is + a terminal problem reconciling the Machine and will contain a succinct + value suitable for machine interpretation. \n This field should + not be set for transitive errors that a controller faces that are + expected to be fixed automatically over time (like service outages), + but instead indicate that something is fundamentally wrong with + the Machine's spec or the configuration of the controller, and that + manual intervention is required. Examples of terminal errors would + be invalid combinations of settings in the spec, values that are + unsupported by the controller, or the responsible controller itself + being critically misconfigured. \n Any transient errors that occur + during the reconciliation of Machines can be added as events to + the Machine object and/or logged in the controller's output." + type: string + ready: + default: false + description: Ready is true when the provider resource is ready. + type: boolean + vmState: + description: VMState indicates the state of the microvm. + type: string type: object type: object served: true diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachinetemplates.yaml new file mode 100644 index 0000000..0685155 --- /dev/null +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_microvmmachinetemplates.yaml @@ -0,0 +1,211 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: microvmmachinetemplates.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MicrovmMachineTemplate + listKind: MicrovmMachineTemplateList + plural: microvmmachinetemplates + shortNames: + - mvmmt + singular: microvmmachinetemplate + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MicrovmMachineTemplate is the Schema for the microvmmachinetemplates + API. + 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: MicrovmMachineTemplateSpec defines the desired state of MicrovmMachineTemplate. + properties: + template: + description: MicrovmMachineTemplateResource describes the data needed + to create a MicrovmMachine from a template. + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map + stored with a resource that may be set by external tools + to store and retrieve arbitrary metadata. They are not queryable + and should be preserved when modifying objects. More info: + http://kubernetes.io/docs/user-guide/annotations' + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used + to organize and categorize (scope and select) objects. May + match selectors of replication controllers and services. + More info: http://kubernetes.io/docs/user-guide/labels' + type: object + type: object + spec: + description: Spec is the specification of the machine. + properties: + initrd: + description: Initrd is an optional initial ramdisk to use. + properties: + filename: + description: Filename is the name of the file in the container + to use. + type: string + image: + description: Image is the container image to use. + type: string + required: + - image + type: object + kernel: + description: Kernel specifies the kernel and its arguments + to use. + properties: + filename: + description: Filename is the name of the file in the container + to use. + type: string + image: + description: Image is the container image to use. + type: string + required: + - image + type: object + kernelCmdline: + default: console=ttyS0 reboot=k panic=1 pci=off i8042.noaux + i8042.nomux i8042.nopnp i8042.dumbkbd + description: KernelCmdLine are the args to use for the kernel + cmdline. + minLength: 5 + type: string + memoryMb: + description: MemoryMb is the amount of memory in megabytes + that the microvm will be allocated. + format: int64 + minimum: 1024 + type: integer + networkInterfaces: + description: NetworkInterfaces specifies the network interfaces + attached to the microvm. + items: + description: NetworkInterface represents a network interface + for the microvm. + properties: + address: + description: Address is an optional IP address to assign + to this interface. If not supplied then DHCP will + be used. + type: string + guestDeviceName: + description: GuestDeviceName is the name of the network + interface to create in the microvm. + type: string + guestMac: + description: GuestMAC allows the specifying of a specific + MAC address to use for the interface. If not supplied + a autogenerated MAC address will be used. + type: string + type: + description: Type is the type of host network interface + type to create to use by the guest. + enum: + - macvtap + - tap + type: string + required: + - guestDeviceName + - type + type: object + minItems: 1 + type: array + providerID: + description: ProviderID is the unique identifier as specified + by the cloud provider. + type: string + rootVolume: + description: RootVolume specifies the volume to use for the + root of the microvm. + properties: + image: + description: Image is the container image to use for the + volume. + type: string + readOnly: + description: ReadOnly specifies that the volume is to + be mounted readonly. + type: boolean + required: + - image + type: object + vcpu: + description: VCPU specifies how many vcpu's the microvm will + be allocated. + format: int64 + minimum: 1 + type: integer + volumes: + description: AdditionalVolumes specifies additional non-root + volumes to attach to the microvm. + items: + description: Volume represents a volume to be attached to + a microvm. + properties: + image: + description: Image is the container image to use for + the volume. + type: string + readOnly: + description: ReadOnly specifies that the volume is to + be mounted readonly. + type: boolean + required: + - image + type: object + type: array + required: + - kernel + - memoryMb + - networkInterfaces + - rootVolume + - vcpu + type: object + required: + - spec + type: object + required: + - template + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 1f923c2..e3d8b5c 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -7,6 +7,7 @@ commonLabels: resources: - bases/infrastructure.cluster.x-k8s.io_microvmclusters.yaml - bases/infrastructure.cluster.x-k8s.io_microvmmachines.yaml +- bases/infrastructure.cluster.x-k8s.io_microvmmachinetemplates.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -14,12 +15,14 @@ patchesStrategicMerge: # patches here are for enabling the conversion webhook for each CRD - patches/webhook_in_microvmclusters.yaml - patches/webhook_in_microvmmachines.yaml +#- patches/webhook_in_microvmmachinetemplates.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD - patches/cainjection_in_microvmclusters.yaml - patches/cainjection_in_microvmmachines.yaml +#- patches/cainjection_in_microvmmachinetemplates.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_microvmmachinetemplates.yaml b/config/crd/patches/cainjection_in_microvmmachinetemplates.yaml new file mode 100644 index 0000000..d1f5d1a --- /dev/null +++ b/config/crd/patches/cainjection_in_microvmmachinetemplates.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: microvmmachinetemplates.infrastructure.cluster.x-k8s.io diff --git a/config/crd/patches/webhook_in_microvmmachinetemplates.yaml b/config/crd/patches/webhook_in_microvmmachinetemplates.yaml new file mode 100644 index 0000000..546a72a --- /dev/null +++ b/config/crd/patches/webhook_in_microvmmachinetemplates.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: microvmmachinetemplates.infrastructure.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/config/rbac/microvmmachinetemplate_editor_role.yaml b/config/rbac/microvmmachinetemplate_editor_role.yaml new file mode 100644 index 0000000..8427b79 --- /dev/null +++ b/config/rbac/microvmmachinetemplate_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit microvmmachinetemplates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: microvmmachinetemplate-editor-role +rules: +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - microvmmachinetemplates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - microvmmachinetemplates/status + verbs: + - get diff --git a/config/rbac/microvmmachinetemplate_viewer_role.yaml b/config/rbac/microvmmachinetemplate_viewer_role.yaml new file mode 100644 index 0000000..431cf70 --- /dev/null +++ b/config/rbac/microvmmachinetemplate_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view microvmmachinetemplates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: microvmmachinetemplate-viewer-role +rules: +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - microvmmachinetemplates + verbs: + - get + - list + - watch +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - microvmmachinetemplates/status + verbs: + - get diff --git a/config/samples/infrastructure_v1alpha1_microvmmachinetemplate.yaml b/config/samples/infrastructure_v1alpha1_microvmmachinetemplate.yaml new file mode 100644 index 0000000..ae04829 --- /dev/null +++ b/config/samples/infrastructure_v1alpha1_microvmmachinetemplate.yaml @@ -0,0 +1,6 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: MicrovmMachineTemplate +metadata: + name: microvmmachinetemplate-sample +spec: + # TODO(user): Add fields here diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 17fcf36..9c4fc10 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -98,3 +98,24 @@ webhooks: resources: - microvmmachine sideEffects: None +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-infrastructure-cluster-x-k8s-io-v1alpha1-microvmmachinetemplate + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.microvmmachinetemplate.infrastructure.cluster.x-k8s.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - microvmmachinetemplates + sideEffects: None diff --git a/docs/adr/0003-no-machinepool-support.md b/docs/adr/0003-no-machinepool-support.md new file mode 100644 index 0000000..982fb22 --- /dev/null +++ b/docs/adr/0003-no-machinepool-support.md @@ -0,0 +1,31 @@ +# Support Machine (and MachineTemplate) but not MachinePool + +* Status: accepted +* Date: 2021-11-1 +* Authors: @richardcase +* Deciders: @jmickey @richardcase @Callisto13 @yitsushi + +## Context + +Cluster API[^1][^2] supports a number of resources kinds that infrastructure providers can implement to create machines for use as Kubernetes nodes: + +* **Machine** - is a declaration for an individual machine. There is always an infrastructure provider counterpart (e.g. AWSMachine, AzureMachine) that knows how to provision the infrastructure for a machine based on a spec. **Machines** are immutable and so the actions required will only be create/delete. +* **MachineTemplate** - is a declaration for a template of a machine. It doesn't relate to a specific machines but the spec it contains will be used to create instances of **Machines** when using the Kubeadm control plane. +* **MachinePools** - are an experimental feature in CAPI and provide a way to declare a dynamic pool of machines where the number of instances can scale up and down. An infrastructure provider provides this via a specific solution to the infrastructure. So CAPA uses Auto Scale Groups (ASG) and CAPZ uses Virtual Machine Scale Sets. + +## Decision + +Cluster API Provider Microvm (CAPMVM) will not support **Machine Pools** initially as [flintlock](https://github.com/weaveworks/flintlock) has no way concept of auto-scaling or machine pools. + +## Consequences + +We will need to implement the following infrastructure kinds: + +* MicrovmCluster (infrastructure counterpart to Cluster) +* MicrovmMachine (infrastructure counterpart to Machine) +* MicrovmMachineTemplate (infrastructure machine template used by Kubeadm Bootstrap Provider) + +We will need to revisit this decision when flintlock supports auto-scaling / pools. + +[^1]: https://cluster-api.sigs.k8s.io/introduction.html +[^2]: https://github.com/kubernetes-sigs/cluster-api diff --git a/main.go b/main.go index f6aecc2..210f90a 100644 --- a/main.go +++ b/main.go @@ -293,6 +293,10 @@ func setupWebhooks(mgr ctrl.Manager) error { return fmt.Errorf("unable to setup MicrovmMachine webhook:%w", err) } + if err := (&infrav1.MicrovmMachineTemplate{}).SetupWebhookWithManager(mgr); err != nil { + return fmt.Errorf("unable to setup MicrovmMachineTemplate webhook:%w", err) + } + return nil } diff --git a/templates/cluster-template.yaml b/templates/cluster-template.yaml new file mode 100644 index 0000000..75f2917 --- /dev/null +++ b/templates/cluster-template.yaml @@ -0,0 +1,113 @@ +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + name: "${CLUSTER_NAME}" +spec: + clusterNetwork: + pods: + cidrBlocks: ["192.168.0.0/16"] + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 + kind: MicrovmCluster + name: "${CLUSTER_NAME}" + controlPlaneRef: + kind: KubeadmControlPlane + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + name: "${CLUSTER_NAME}-control-plane" +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: MicrovmCluster +metadata: + name: "${CLUSTER_NAME}" +spec: {} +--- +kind: KubeadmControlPlane +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + version: "${KUBERNETES_VERSION}" + machineTemplate: + infrastructureRef: + kind: MicrovmMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + name: "${CLUSTER_NAME}-control-plane" + kubeadmConfigSpec: + initConfiguration: + nodeRegistration: + kubeletExtraArgs: + provider-id: "PROVIDER_ID" + clusterConfiguration: {} + joinConfiguration: + nodeRegistration: + kubeletExtraArgs: + provider-id: "PROVIDER_ID" +--- +kind: MicrovmMachineTemplate +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + template: + spec: + vcpu: 2 + memoryMb: 2048 + rootVolume: + image: {MVM_ROOT_IMAGE} + kernel: {MVM_KERNEL_IMAGE} + networkInterfaces: + - guestDeviceName: "eth0" + type: "macvtap" +--- +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineDeployment +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + clusterName: "${CLUSTER_NAME}" + replicas: ${WORKER_MACHINE_COUNT} + selector: + matchLabels: + template: + spec: + clusterName: "${CLUSTER_NAME}" + version: "${KUBERNETES_VERSION}" + bootstrap: + configRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + infrastructureRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 + kind: MicrovmMachineTemplate +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: MicrovmMachineTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + vcpu: 2 + memoryMb: 2048 + rootVolume: + image: {MVM_ROOT_IMAGE} + kernel: {MVM_KERNEL_IMAGE} + networkInterfaces: + - guestDeviceName: "eth0" + type: "macvtap" +--- +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: KubeadmConfigTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + kubeletExtraArgs: + provider-id: "PROVIDER_ID"