]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
python-common/smb: move network conversion validation func to common
authorJohn Mulligan <jmulligan@redhat.com>
Fri, 26 Sep 2025 18:22:12 +0000 (14:22 -0400)
committerJohn Mulligan <jmulligan@redhat.com>
Thu, 29 Jan 2026 17:07:04 +0000 (12:07 -0500)
Extract code from the service_spec.py file that parses, validates and
converts network or ip address strings into a network object into a new
file so that it can be re-used more widely later.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/python-common/ceph/deployment/service_spec.py
src/python-common/ceph/smb/network.py [new file with mode: 0644]

index 932044741ca6b704fbe1ed9e6630b7a3616b05be..18b6bafe4d2d4944ed734a0e11483bacf10e60e4 100644 (file)
@@ -40,6 +40,7 @@ from ceph.deployment.utils import verify_boolean, verify_enum, verify_int
 from ceph.deployment.utils import parse_combined_pem_file
 from ceph.utils import is_hex
 from ceph.smb import constants as smbconst
+from ceph.smb import network as smbnet
 
 ServiceSpecT = TypeVar('ServiceSpecT', bound='ServiceSpec')
 FuncT = TypeVar('FuncT', bound=Callable)
@@ -3601,29 +3602,13 @@ class SMBClusterBindIPSpec:
         self.validate()
 
     def validate(self) -> None:
-        if self.address and self.network:
-            raise SpecValidationError('only one of address or network may be given')
-        if not (self.address or self.network):
-            raise SpecValidationError('one of address or network is required')
-        if self.address:
-            # verify that address is an address
-            try:
-                ip_address(self.address)
-            except ValueError as err:
-                raise SpecValidationError(
-                    f'Cannot parse address {self.address}'
-                ) from err
-        # but we internallly store a list of networks
-        # this is slight bit of YAGNI violation, but I actually plan on
-        # adding IP ranges soon.
-        addr = self.network if self.network else self.address
         try:
-            assert addr
-            self._networks = [ip_network(addr)]
+            netval = smbnet.to_network(
+                network=self.network, address=self.address
+            )
+            self._networks = [netval]
         except ValueError as err:
-            raise SpecValidationError(
-                f'Cannot parse network address {addr}'
-            ) from err
+            raise SpecValidationError(str(err)) from err
 
     def as_networks(self) -> List[Union[IPv4Network, IPv6Network]]:
         """Return a list of one or more IPv4 or IPv6 network objects."""
diff --git a/src/python-common/ceph/smb/network.py b/src/python-common/ceph/smb/network.py
new file mode 100644 (file)
index 0000000..cfd1752
--- /dev/null
@@ -0,0 +1,45 @@
+# Shared functions for working with networking (addresses, etc) across
+# multiple ceph smb components.
+
+from typing import Optional, Union
+
+import ipaddress
+
+
+IPNetwork = Union[ipaddress.IPv4Network, ipaddress.IPv6Network]
+
+
+def to_network(
+    *,
+    network: Optional[str] = None,
+    address: Optional[str] = None,
+) -> IPNetwork:
+    """Parse and convert an IP address or IP network string into a network
+    object so that calling code only needs to manage network objects (vs
+    seperate address and network objects). The input values may be for either
+    IPv4 or IPv6.
+    If the input value is an address rather than a network the resulting
+    network object will have a prefixlen value equal to the length of the
+    maximum prefixlen - /32 for IPv4 and /128 for IPv6.
+    Only keyword arguments are supported.
+    """
+    if address and network:
+        raise ValueError('only one of address or network may be given')
+    if not (address or network):
+        raise ValueError('one of address or network is required')
+
+    if address:
+        # verify that address is actually an address and doesn't contain a
+        # network value (that would be accepted by ip_network).
+        try:
+            ipaddress.ip_address(address)
+        except ValueError as err:
+            raise ValueError(f'Cannot parse address {address}') from err
+
+    addr = network if network else address
+    try:
+        assert addr
+        nw = ipaddress.ip_network(addr)
+    except ValueError as err:
+        raise ValueError(f'Cannot parse network address {addr}') from err
+    return nw