From 422eb463d413da812eabc28706e507a9910d7b53 Mon Sep 17 00:00:00 2001 From: aapostoliuk Date: Mon, 13 Nov 2023 11:17:23 +0200 Subject: accel-ppp: T5688: Standardized pool configuration in accel-ppp Standardized pool configuration for all accel-ppp services. 1. Only named pools are used now. 2. Allows all services to use range in x.x.x.x/mask and x.x.x.x-x.x.x.y format 3. next-pool can be used in all services 2. Allows to use in ipoe gw-ip-address without pool configuration which allows to use Fraimed-IP-Address attribute by radius. 3. Default pool name should be explicidly configured with default-pool. 4. In ipoe netmask and range subnet can be different. --- src/conf_mode/service_ipoe-server.py | 102 +++-------------------------------- 1 file changed, 6 insertions(+), 96 deletions(-) (limited to 'src/conf_mode/service_ipoe-server.py') diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index b70e32373..36f00dec5 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -15,17 +15,17 @@ # along with this program. If not, see . import os -import jmespath from sys import exit from vyos.config import Config from vyos.configdict import get_accel_dict -from vyos.configverify import verify_accel_ppp_base_service from vyos.configverify import verify_interface_exists from vyos.template import render from vyos.utils.process import call from vyos.utils.dict import dict_search +from vyos.accel_ppp_util import get_pools_in_order +from vyos.accel_ppp_util import verify_accel_ppp_ip_pool from vyos import ConfigError from vyos import airbag airbag.enable() @@ -35,87 +35,6 @@ ipoe_conf = '/run/accel-pppd/ipoe.conf' ipoe_chap_secrets = '/run/accel-pppd/ipoe.chap-secrets' -def get_pools_in_order(data: dict) -> list: - """Return a list of dictionaries representing pool data in the order - in which they should be allocated. Pool must be defined before we can - use it with 'next-pool' option. - - Args: - data: A dictionary of pool data, where the keys are pool names and the - values are dictionaries containing the 'subnet' key and the optional - 'next_pool' key. - - Returns: - list: A list of dictionaries - - Raises: - ValueError: If a 'next_pool' key references a pool name that - has not been defined. - ValueError: If a circular reference is found in the 'next_pool' keys. - - Example: - config_data = { - ... 'first-pool': { - ... 'next_pool': 'second-pool', - ... 'subnet': '192.0.2.0/25' - ... }, - ... 'second-pool': { - ... 'next_pool': 'third-pool', - ... 'subnet': '203.0.113.0/25' - ... }, - ... 'third-pool': { - ... 'subnet': '198.51.100.0/24' - ... }, - ... 'foo': { - ... 'subnet': '100.64.0.0/24', - ... 'next_pool': 'second-pool' - ... } - ... } - - % get_pools_in_order(config_data) - [{'third-pool': {'subnet': '198.51.100.0/24'}}, - {'second-pool': {'next_pool': 'third-pool', 'subnet': '203.0.113.0/25'}}, - {'first-pool': {'next_pool': 'second-pool', 'subnet': '192.0.2.0/25'}}, - {'foo': {'next_pool': 'second-pool', 'subnet': '100.64.0.0/24'}}] - """ - pools = [] - unresolved_pools = {} - - for pool, pool_config in data.items(): - if 'next_pool' not in pool_config: - pools.insert(0, {pool: pool_config}) - else: - unresolved_pools[pool] = pool_config - - while unresolved_pools: - resolved_pools = [] - - for pool, pool_config in unresolved_pools.items(): - next_pool_name = pool_config['next_pool'] - - if any(p for p in pools if next_pool_name in p): - index = next( - (i for i, p in enumerate(pools) if next_pool_name in p), - None) - pools.insert(index + 1, {pool: pool_config}) - resolved_pools.append(pool) - elif next_pool_name in unresolved_pools: - # next pool not yet resolved - pass - else: - raise ValueError( - f"Pool '{next_pool_name}' not defined in configuration data" - ) - - if not resolved_pools: - raise ValueError("Circular reference in configuration data") - - for pool in resolved_pools: - unresolved_pools.pop(pool) - - return pools - - def get_config(config=None): if config: conf = config @@ -128,18 +47,11 @@ def get_config(config=None): # retrieve common dictionary keys ipoe = get_accel_dict(conf, base, ipoe_chap_secrets) - if jmespath.search('client_ip_pool.name', ipoe): - dict_named_pools = jmespath.search('client_ip_pool.name', ipoe) + if dict_search('client_ip_pool', ipoe): # Multiple named pools require ordered values T5099 - ipoe['ordered_named_pools'] = get_pools_in_order(dict_named_pools) - # T5099 'next-pool' option - if jmespath.search('client_ip_pool.name.*.next_pool', ipoe): - for pool, pool_config in ipoe['client_ip_pool']['name'].items(): - if 'next_pool' in pool_config: - ipoe['first_named_pool'] = pool - ipoe['first_named_pool_subnet'] = pool_config - break + ipoe['ordered_named_pools'] = get_pools_in_order(dict_search('client_ip_pool', ipoe)) + ipoe['server_type'] = 'ipoe' return ipoe @@ -156,9 +68,7 @@ def verify(ipoe): raise ConfigError('Option "client-subnet" incompatible with "vlan"!' 'Use "ipoe client-ip-pool" instead.') - #verify_accel_ppp_base_service(ipoe, local_users=False) - # IPoE server does not have 'gateway' option in the CLI - # we cannot use configverify.py verify_accel_ppp_base_service for ipoe-server + verify_accel_ppp_ip_pool(ipoe) if dict_search('authentication.mode', ipoe) == 'radius': if not dict_search('authentication.radius.server', ipoe): -- cgit v1.2.3