From d5054b21cee9d2bc0d247af7253083b8531949df Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Date: Fri, 30 Aug 2024 22:33:25 +0500 Subject: [PATCH] Add a validation util to verify used subnets --- .../middlewared/plugins/docker/update.py | 2 +- .../plugins/docker/validation_utils.py | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/middlewared/middlewared/plugins/docker/validation_utils.py diff --git a/src/middlewared/middlewared/plugins/docker/update.py b/src/middlewared/middlewared/plugins/docker/update.py index d4d0d455375bb..40d254d86388f 100644 --- a/src/middlewared/middlewared/plugins/docker/update.py +++ b/src/middlewared/middlewared/plugins/docker/update.py @@ -41,7 +41,7 @@ class Config: Dict( 'address_pool', IPAddr('base', cidr=True), - Int('size', validators=[Range(min_=0, max_=32)]) + Int('size', validators=[Range(min_=1, max_=32)]) ) ]), update=True, diff --git a/src/middlewared/middlewared/plugins/docker/validation_utils.py b/src/middlewared/middlewared/plugins/docker/validation_utils.py new file mode 100644 index 0000000000000..9ec1f71613c4c --- /dev/null +++ b/src/middlewared/middlewared/plugins/docker/validation_utils.py @@ -0,0 +1,41 @@ +import ipaddress + +from middlewared.schema import ValidationErrors + + +def validate_address_pools(system_ips: list[dict], user_specified_networks: list[dict]): + verrors = ValidationErrors() + network_cidrs = set([ + ipaddress.ip_network(f'{ip["address"]}/{ip["network"]}', False) + for ip in system_ips + ]) + seen_networks = set() + for index, user_network in enumerate(user_specified_networks): + base_network = ipaddress.ip_network(user_network['base'], False) + subnet_prefix = int(user_network['base'].split('/')[-1]) + + # Validate subnet size vs. base network + if subnet_prefix > user_network['size']: + verrors.add( + f'docker_update.address_pools.{index}.base', + f'Base network {user_network["base"]} cannot be smaller than ' + f'the specified subnet size {user_network["size"]}' + ) + + # Validate no overlaps with system networks + if any(base_network.overlaps(system_network) for system_network in network_cidrs): + verrors.add( + f'docker_update.address_pools.{index}.base', + f'Base network {user_network["base"]} overlaps with an existing system network' + ) + + # Validate no duplicate networks + if base_network in seen_networks: + verrors.add( + f'docker_update.address_pools.{index}.base', + f'Base network {user_network["base"]} is a duplicate of another specified network' + ) + + seen_networks.add(base_network) + + verrors.check()