diff --git a/internal/nvmeof/controller/controllerserver.go b/internal/nvmeof/controller/controllerserver.go index 7888d13ae45..81aeeace355 100644 --- a/internal/nvmeof/controller/controllerserver.go +++ b/internal/nvmeof/controller/controllerserver.go @@ -785,10 +785,13 @@ func (cs *Server) createNVMeoFResources( } // setup listeners (if provided, otherwise it will be set by gateway based on network mask) - err = setupDefaultListenersValues(params["listeners"], nvmeofData) + listeners, err := parseListeners(params["listeners"]) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse listeners: %w", err) } + nvmeofData.ListenerInfo = listeners + // If listener port or address is empty, it will be set to default. + nvmeofData.SetListenersWithDefaults() // If dhchapMode was explicitly provided and is not "none", and authenticationKMSID is empty, // use a default KMS ID - RBD metadata KMS. @@ -1330,29 +1333,3 @@ func connectGateway(ctx context.Context, config *nvmeof.GatewayConfig) (*nvmeof. return gateway, nil } - -// setupDefaultListeners validates and sets up default values for NVMe-oF listeners. -// if listeners are provided, it ensures they are fully populated with -// default values if needed (port and address). -func setupDefaultListenersValues(listenersJSON string, info *nvmeof.NVMeoFVolumeData) error { - // Parse listeners from JSON - listeners, err := parseListeners(listenersJSON) - if err != nil { - return fmt.Errorf("failed to parse listeners: %w", err) - } - - // ensure listeners are fully populated with default values if needed (port and address) - // before storing in metadata and creating subsystem/listeners - for i := range listeners { - if listeners[i].Port == 0 { - listeners[i].Port = 4420 - } - // if address is empty, set it to default 0.0.0.0 - if listeners[i].Address == "" { - listeners[i].Address = "0.0.0.0" - } - } - info.ListenerInfo = listeners - - return nil -} diff --git a/internal/nvmeof/volume.go b/internal/nvmeof/volume.go index c948563d9a4..c0c1a4dda12 100644 --- a/internal/nvmeof/volume.go +++ b/internal/nvmeof/volume.go @@ -30,3 +30,17 @@ type NVMeoFSecurityConfig struct { DhchapMode string AuthenticationKMSID string } + +// SetListenersWithDefaults applies default values to the existing ListenerInfo. +// If port is 0, it defaults to 4420. +// If address is empty, it defaults to 0.0.0.0. +func (v *NVMeoFVolumeData) SetListenersWithDefaults() { + for i := range v.ListenerInfo { + if v.ListenerInfo[i].Port == 0 { + v.ListenerInfo[i].Port = 4420 + } + if v.ListenerInfo[i].Address == "" { + v.ListenerInfo[i].Address = "0.0.0.0" + } + } +} diff --git a/internal/nvmeof/volume_test.go b/internal/nvmeof/volume_test.go new file mode 100644 index 00000000000..ca9027eb4f1 --- /dev/null +++ b/internal/nvmeof/volume_test.go @@ -0,0 +1,52 @@ +/* +Copyright 2026 The Ceph-CSI 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 nvmeof + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSetListenersWithDefaults(t *testing.T) { + t.Parallel() + tests := []struct { + in []ListenerDetails + out []ListenerDetails + }{ + { + in: []ListenerDetails{ + {Hostname: "nvmeof-gw-a", GatewayAddress: GatewayAddress{Port: 0, Address: ""}}, + {Hostname: "nvmeof-gw-b", GatewayAddress: GatewayAddress{Port: 1234, Address: ""}}, + {Hostname: "nvmeof-gw-c", GatewayAddress: GatewayAddress{Port: 0, Address: "10.92.3.12"}}, + {Hostname: "nvmeof-gw-d", GatewayAddress: GatewayAddress{Port: 1234, Address: "10.92.3.13"}}, + }, + out: []ListenerDetails{ + {Hostname: "nvmeof-gw-a", GatewayAddress: GatewayAddress{Port: 4420, Address: "0.0.0.0"}}, + {Hostname: "nvmeof-gw-b", GatewayAddress: GatewayAddress{Port: 1234, Address: "0.0.0.0"}}, + {Hostname: "nvmeof-gw-c", GatewayAddress: GatewayAddress{Port: 4420, Address: "10.92.3.12"}}, + {Hostname: "nvmeof-gw-d", GatewayAddress: GatewayAddress{Port: 1234, Address: "10.92.3.13"}}, + }, + }, + } + + for _, test := range tests { + vol := &NVMeoFVolumeData{ListenerInfo: test.in} + vol.SetListenersWithDefaults() + require.Equal(t, test.out, vol.ListenerInfo) + } +}