diff --git a/api/v1alpha1/httpbootconfig_types.go b/api/v1alpha1/httpbootconfig_types.go index f68b0536..0bdd7b36 100644 --- a/api/v1alpha1/httpbootconfig_types.go +++ b/api/v1alpha1/httpbootconfig_types.go @@ -12,7 +12,7 @@ import ( type HTTPBootConfigSpec struct { SystemUUID string `json:"systemUUID,omitempty"` IgnitionSecretRef *corev1.LocalObjectReference `json:"ignitionSecretRef,omitempty"` - SystemIP string `json:"systemIP,omitempty"` + SystemIPs []string `json:"systemIPs,omitempty"` UKIURL string `json:"ukiURL,omitempty"` } diff --git a/api/v1alpha1/ipxebootconfig_types.go b/api/v1alpha1/ipxebootconfig_types.go index ed843c1b..b9d96a9b 100644 --- a/api/v1alpha1/ipxebootconfig_types.go +++ b/api/v1alpha1/ipxebootconfig_types.go @@ -14,8 +14,8 @@ import ( // IPXEBootConfigSpec defines the desired state of IPXEBootConfig type IPXEBootConfigSpec struct { // Important: Run "make" to regenerate code after modifying this file - SystemUUID string `json:"systemUUID,omitempty"` - SystemIP string `json:"systemIP,omitempty"` // TODO: Add the custom serialization. For now validate at the controller. + SystemUUID string `json:"systemUUID,omitempty"` + SystemIPs []string `json:"systemIPs,omitempty"` // TODO: Add the custom serialization. For now validate at the controller. // TODO: remove image as this is not needed Image string `json:"image,omitempty"` KernelURL string `json:"kernelURL,omitempty"` @@ -35,9 +35,6 @@ const ( IPXEBootConfigStateError IPXEBootConfigState = "Error" ) -const DefaultIgnitionKey = "ignition" -const DefaultIPXEScriptKey = "ipxe-script" - // IPXEBootConfigStatus defines the observed state of IPXEBootConfig type IPXEBootConfigStatus struct { // Important: Run "make" to regenerate code after modifying this file @@ -68,6 +65,13 @@ type IPXEBootConfigList struct { Items []IPXEBootConfig `json:"items"` } +const ( + DefaultIgnitionKey = "ignition" + DefaultIPXEScriptKey = "ipxe-script" + SystemUUIDIndexKey = "spec.systemUUID" + SystemIPIndexKey = "spec.systemIPs" +) + func init() { SchemeBuilder.Register(&IPXEBootConfig{}, &IPXEBootConfigList{}) } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index b6d33221..edf75dba 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -79,6 +79,11 @@ func (in *HTTPBootConfigSpec) DeepCopyInto(out *HTTPBootConfigSpec) { *out = new(v1.LocalObjectReference) **out = **in } + if in.SystemIPs != nil { + in, out := &in.SystemIPs, &out.SystemIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPBootConfigSpec. @@ -168,6 +173,11 @@ func (in *IPXEBootConfigList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IPXEBootConfigSpec) DeepCopyInto(out *IPXEBootConfigSpec) { *out = *in + if in.SystemIPs != nil { + in, out := &in.SystemIPs, &out.SystemIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.IgnitionSecretRef != nil { in, out := &in.IgnitionSecretRef, &out.IgnitionSecretRef *out = new(v1.LocalObjectReference) diff --git a/cmd/main.go b/cmd/main.go index f1797a50..7bb912d8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -39,11 +39,6 @@ var ( serverLog = zap.New(zap.UseDevMode(true)) ) -const ( - systemUUIDIndexKey = "spec.systemUUID" - systemIPIndexKey = "spec.systemIP" -) - const ( // core controllers ipxeBootConfigController = "ipxebootconfig" @@ -223,12 +218,12 @@ func main() { os.Exit(1) } - if err := IndexIPXEBootConfigBySystemIP(ctx, mgr); err != nil { - setupLog.Error(err, "unable to set up indexer for IPXEBootConfig SystemIP") + if err := IndexIPXEBootConfigBySystemIPs(ctx, mgr); err != nil { + setupLog.Error(err, "unable to set up indexer for IPXEBootConfig SystemIPs") os.Exit(1) } - if err := IndexHTTPBootConfigBySystemIP(ctx, mgr); err != nil { + if err := IndexHTTPBootConfigBySystemIPs(ctx, mgr); err != nil { setupLog.Error(err, "unable to set up indexer for HTTPBootConfig SystemIP") os.Exit(1) } @@ -250,7 +245,7 @@ func IndexIPXEBootConfigBySystemUUID(ctx context.Context, mgr ctrl.Manager) erro return mgr.GetFieldIndexer().IndexField( ctx, &bootv1alpha1.IPXEBootConfig{}, - systemUUIDIndexKey, + bootv1alpha1.SystemUUIDIndexKey, func(Obj client.Object) []string { ipxeBootConfig := Obj.(*bootv1alpha1.IPXEBootConfig) return []string{ipxeBootConfig.Spec.SystemUUID} @@ -258,13 +253,13 @@ func IndexIPXEBootConfigBySystemUUID(ctx context.Context, mgr ctrl.Manager) erro ) } -func IndexIPXEBootConfigBySystemIP(ctx context.Context, mgr ctrl.Manager) error { +func IndexIPXEBootConfigBySystemIPs(ctx context.Context, mgr ctrl.Manager) error { return mgr.GetFieldIndexer().IndexField( ctx, &bootv1alpha1.IPXEBootConfig{}, - systemIPIndexKey, + bootv1alpha1.SystemIPIndexKey, func(Obj client.Object) []string { ipxeBootConfig := Obj.(*bootv1alpha1.IPXEBootConfig) - return []string{ipxeBootConfig.Spec.SystemIP} + return ipxeBootConfig.Spec.SystemIPs }, ) } @@ -273,7 +268,7 @@ func IndexHTTPBootConfigBySystemUUID(ctx context.Context, mgr ctrl.Manager) erro return mgr.GetFieldIndexer().IndexField( ctx, &bootv1alpha1.HTTPBootConfig{}, - systemUUIDIndexKey, + bootv1alpha1.SystemUUIDIndexKey, func(Obj client.Object) []string { HTTPBootConfig := Obj.(*bootv1alpha1.HTTPBootConfig) return []string{HTTPBootConfig.Spec.SystemUUID} @@ -281,14 +276,14 @@ func IndexHTTPBootConfigBySystemUUID(ctx context.Context, mgr ctrl.Manager) erro ) } -func IndexHTTPBootConfigBySystemIP(ctx context.Context, mgr ctrl.Manager) error { +func IndexHTTPBootConfigBySystemIPs(ctx context.Context, mgr ctrl.Manager) error { return mgr.GetFieldIndexer().IndexField( ctx, &bootv1alpha1.HTTPBootConfig{}, - systemIPIndexKey, + bootv1alpha1.SystemIPIndexKey, func(Obj client.Object) []string { HTTPBootConfig := Obj.(*bootv1alpha1.HTTPBootConfig) - return []string{HTTPBootConfig.Spec.SystemIP} + return HTTPBootConfig.Spec.SystemIPs }, ) } diff --git a/config/crd/bases/boot.ironcore.dev_httpbootconfigs.yaml b/config/crd/bases/boot.ironcore.dev_httpbootconfigs.yaml index 2adfc4b7..d9f007bd 100644 --- a/config/crd/bases/boot.ironcore.dev_httpbootconfigs.yaml +++ b/config/crd/bases/boot.ironcore.dev_httpbootconfigs.yaml @@ -64,8 +64,10 @@ spec: type: string type: object x-kubernetes-map-type: atomic - systemIP: - type: string + systemIPs: + items: + type: string + type: array systemUUID: type: string ukiURL: diff --git a/config/crd/bases/boot.ironcore.dev_ipxebootconfigs.yaml b/config/crd/bases/boot.ironcore.dev_ipxebootconfigs.yaml index e6e931ef..85dc32e7 100644 --- a/config/crd/bases/boot.ironcore.dev_ipxebootconfigs.yaml +++ b/config/crd/bases/boot.ironcore.dev_ipxebootconfigs.yaml @@ -94,8 +94,10 @@ spec: type: string squashfsURL: type: string - systemIP: - type: string + systemIPs: + items: + type: string + type: array systemUUID: description: 'Important: Run "make" to regenerate code after modifying this file' diff --git a/internal/controller/httpbootconfig_controller.go b/internal/controller/httpbootconfig_controller.go index cdb8dc5e..7117763f 100644 --- a/internal/controller/httpbootconfig_controller.go +++ b/internal/controller/httpbootconfig_controller.go @@ -88,7 +88,7 @@ func (r *HTTPBootConfigReconciler) ensureIgnition(ctx context.Context, _ logr.Lo return bootv1alpha1.HTTPBootConfigStateReady, nil } -func (r *HTTPBootConfigReconciler) delete(_ context.Context, log logr.Logger, HTTPBootConfig *bootv1alpha1.HTTPBootConfig) (ctrl.Result, error) { +func (r *HTTPBootConfigReconciler) delete(_ context.Context, log logr.Logger, _ *bootv1alpha1.HTTPBootConfig) (ctrl.Result, error) { log.V(1).Info("Deleting HTTPBootConfig") // TODO diff --git a/internal/controller/ipxebootconfig_controller.go b/internal/controller/ipxebootconfig_controller.go index 58a5a01e..06d33886 100644 --- a/internal/controller/ipxebootconfig_controller.go +++ b/internal/controller/ipxebootconfig_controller.go @@ -87,7 +87,7 @@ func (r *IPXEBootConfigReconciler) ensureIgnition(ctx context.Context, _ logr.Lo return bootv1alpha1.IPXEBootConfigStateReady, nil } -func (r *IPXEBootConfigReconciler) delete(_ context.Context, log logr.Logger, ipxeBootConfig *bootv1alpha1.IPXEBootConfig) (ctrl.Result, error) { +func (r *IPXEBootConfigReconciler) delete(_ context.Context, log logr.Logger, _ *bootv1alpha1.IPXEBootConfig) (ctrl.Result, error) { log.V(1).Info("Deleting ipxeBootConfig") // TODO diff --git a/internal/controller/serverbootconfiguration_controller.go b/internal/controller/serverbootconfiguration_controller.go index b3e7830d..bff6ab3e 100644 --- a/internal/controller/serverbootconfiguration_controller.go +++ b/internal/controller/serverbootconfiguration_controller.go @@ -79,11 +79,11 @@ func (r *ServerBootConfigurationReconciler) reconcile(ctx context.Context, log l } log.V(1).Info("Got system UUID from BootConfig", "systemUUID", systemUUID) - systemIP, err := r.getSystemIPFromBootConfig(ctx, config) + systemIPs, err := r.getSystemIPFromBootConfig(ctx, config) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to get system IP from BootConfig: %w", err) } - log.V(1).Info("Got system IP from BootConfig", "systemIP", systemIP) + log.V(1).Info("Got system IP from BootConfig", "systemIPs", systemIPs) kernelURL, initrdURL, squashFSURL, err := r.getImageDetailsFromConfig(ctx, config) if err != nil { @@ -102,7 +102,7 @@ func (r *ServerBootConfigurationReconciler) reconcile(ctx context.Context, log l }, Spec: v1alpha1.IPXEBootConfigSpec{ SystemUUID: systemUUID, - SystemIP: systemIP, + SystemIPs: systemIPs, KernelURL: kernelURL, InitrdURL: initrdURL, SquashfsURL: squashFSURL, @@ -162,22 +162,22 @@ func (r *ServerBootConfigurationReconciler) getSystemUUIDFromBootConfig(ctx cont return server.Spec.UUID, nil } -func (r *ServerBootConfigurationReconciler) getSystemIPFromBootConfig(ctx context.Context, config *metalv1alpha1.ServerBootConfiguration) (string, error) { +func (r *ServerBootConfigurationReconciler) getSystemIPFromBootConfig(ctx context.Context, config *metalv1alpha1.ServerBootConfiguration) ([]string, error) { server := &metalv1alpha1.Server{} if err := r.Get(ctx, client.ObjectKey{Name: config.Spec.ServerRef.Name}, server); err != nil { - return "", fmt.Errorf("failed to get Server: %w", err) + return nil, fmt.Errorf("failed to get Server: %w", err) } + systemIPs := []string{} for _, nic := range server.Status.NetworkInterfaces { - // TODO: we will use the first NIC for now. Need to decide later what to do about it. - return nic.IP.String(), nil + systemIPs = append(systemIPs, nic.IP.String()) + return systemIPs, nil } - return "", nil + return nil, nil } func (r *ServerBootConfigurationReconciler) getImageDetailsFromConfig(ctx context.Context, config *metalv1alpha1.ServerBootConfiguration) (string, string, string, error) { - // http://[2a10:afc0:e013:d002::]:30007/image?imageName=ghcr.io/ironcore-dev/os-images/gardenlinux&version=1443.3&layerName=initramfs imageDetails := strings.Split(config.Spec.Image, ":") if len(imageDetails) != 2 { return "", "", "", fmt.Errorf("invalid image format") diff --git a/internal/controller/serverbootconfiguration_controller_test.go b/internal/controller/serverbootconfiguration_controller_test.go index b8d10855..fca2a6a3 100644 --- a/internal/controller/serverbootconfiguration_controller_test.go +++ b/internal/controller/serverbootconfiguration_controller_test.go @@ -88,7 +88,7 @@ var _ = Describe("ServerBootConfiguration Controller", func() { BlockOwnerDeletion: ptr.To(true), })), HaveField("Spec.SystemUUID", server.Spec.UUID), - HaveField("Spec.SystemIP", "1.1.1.1"), + HaveField("Spec.SystemIPs", ContainElement("1.1.1.1")), HaveField("Spec.KernelURL", "http://localhost:5000/image?imageName=foo&version=bar&layerName=application/vnd.ironcore.image.vmlinuz.v1alpha1.vmlinuz"), HaveField("Spec.InitrdURL", "http://localhost:5000/image?imageName=foo&version=bar&layerName=application/vnd.ironcore.image.initramfs.v1alpha1.initramfs"), HaveField("Spec.SquashfsURL", "http://localhost:5000/image?imageName=foo&version=bar&layerName=application/vnd.ironcore.image.squashfs.v1alpha1.squashfs"), diff --git a/server/bootserver.go b/server/bootserver.go index d4947853..d15848e7 100644 --- a/server/bootserver.go +++ b/server/bootserver.go @@ -49,7 +49,7 @@ func RunBootServer(ipxeServerAddr string, ipxeServiceURL string, k8sClient clien } ipxeBootConfigList := &bootv1alpha1.IPXEBootConfigList{} - err := k8sClient.List(r.Context(), ipxeBootConfigList, client.MatchingFields{"spec.systemUUID": uuid}) + err := k8sClient.List(r.Context(), ipxeBootConfigList, client.MatchingFields{bootv1alpha1.SystemUUIDIndexKey: uuid}) if client.IgnoreNotFound(err) != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return @@ -93,7 +93,7 @@ func handleIPXE(w http.ResponseWriter, r *http.Request, k8sClient client.Client, var ipxeConfigs bootv1alpha1.IPXEBootConfigList for _, ip := range clientIPs { - if err := k8sClient.List(ctx, &ipxeConfigs, client.MatchingFields{"spec.systemIP": ip}); err != nil { + if err := k8sClient.List(ctx, &ipxeConfigs, client.MatchingFields{bootv1alpha1.SystemIPIndexKey: ip}); err != nil { log.Info("Failed to list IPXEBootConfig for IP", "IP", ip, "error", err) continue } @@ -146,7 +146,7 @@ func handleIgnitionIPXEBoot(w http.ResponseWriter, r *http.Request, k8sClient cl ctx := r.Context() ipxeBootConfigList := &bootv1alpha1.IPXEBootConfigList{} - if err := k8sClient.List(ctx, ipxeBootConfigList, client.MatchingFields{"spec.systemUUID": uuid}); err != nil { + if err := k8sClient.List(ctx, ipxeBootConfigList, client.MatchingFields{bootv1alpha1.SystemUUIDIndexKey: uuid}); err != nil { http.Error(w, "Resource Not Found", http.StatusNotFound) log.Info("Failed to find IPXEBootConfig", "error", err.Error()) return @@ -211,7 +211,7 @@ func handleIgnitionHTTPBoot(w http.ResponseWriter, r *http.Request, k8sClient cl ctx := r.Context() HTTPBootConfigList := &bootv1alpha1.HTTPBootConfigList{} - if err := k8sClient.List(ctx, HTTPBootConfigList, client.MatchingFields{"spec.systemUUID": uuid}); err != nil { + if err := k8sClient.List(ctx, HTTPBootConfigList, client.MatchingFields{bootv1alpha1.SystemUUIDIndexKey: uuid}); err != nil { http.Error(w, "Resource Not Found", http.StatusNotFound) log.Info("Failed to find HTTPBootConfigList", "error", err.Error()) return @@ -297,7 +297,7 @@ func handleHTTPBoot(w http.ResponseWriter, r *http.Request, k8sClient client.Cli var httpBootConfigs bootv1alpha1.HTTPBootConfigList for _, ip := range clientIPs { - if err := k8sClient.List(ctx, &httpBootConfigs, client.MatchingFields{"spec.systemIP": ip}); err != nil { + if err := k8sClient.List(ctx, &httpBootConfigs, client.MatchingFields{bootv1alpha1.SystemIPIndexKey: ip}); err != nil { log.Info("Failed to list HTTPBootConfig for IP", "IP", ip, "error", err) continue }