diff options
Diffstat (limited to 'src/services')
26 files changed, 237 insertions, 55 deletions
| diff --git a/src/services/api/graphql/bindings.py b/src/services/api/graphql/bindings.py index ebf745f32..7380dbb5f 100644 --- a/src/services/api/graphql/bindings.py +++ b/src/services/api/graphql/bindings.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/generate/generate_schema.py b/src/services/api/graphql/generate/generate_schema.py index dd5e7ea56..bb36a4c04 100755 --- a/src/services/api/graphql/generate/generate_schema.py +++ b/src/services/api/graphql/generate/generate_schema.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2023 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/api/graphql/generate/schema_from_composite.py b/src/services/api/graphql/generate/schema_from_composite.py index 06e74032d..e370961dc 100755 --- a/src/services/api/graphql/generate/schema_from_composite.py +++ b/src/services/api/graphql/generate/schema_from_composite.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/api/graphql/generate/schema_from_config_session.py b/src/services/api/graphql/generate/schema_from_config_session.py index 1d5ff1e53..61ac9bd39 100755 --- a/src/services/api/graphql/generate/schema_from_config_session.py +++ b/src/services/api/graphql/generate/schema_from_config_session.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/api/graphql/generate/schema_from_op_mode.py b/src/services/api/graphql/generate/schema_from_op_mode.py index ab7cb691f..8cfd60769 100755 --- a/src/services/api/graphql/generate/schema_from_op_mode.py +++ b/src/services/api/graphql/generate/schema_from_op_mode.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2023 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/api/graphql/graphql/auth_token_mutation.py b/src/services/api/graphql/graphql/auth_token_mutation.py index c74364603..a8020d149 100644 --- a/src/services/api/graphql/graphql/auth_token_mutation.py +++ b/src/services/api/graphql/graphql/auth_token_mutation.py @@ -1,4 +1,4 @@ -# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/graphql/directives.py b/src/services/api/graphql/graphql/directives.py index 3927aee58..037f09204 100644 --- a/src/services/api/graphql/graphql/directives.py +++ b/src/services/api/graphql/graphql/directives.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/graphql/mutations.py b/src/services/api/graphql/graphql/mutations.py index 0b391c070..c979d06e8 100644 --- a/src/services/api/graphql/graphql/mutations.py +++ b/src/services/api/graphql/graphql/mutations.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/graphql/queries.py b/src/services/api/graphql/graphql/queries.py index 9303fe909..3a8d12344 100644 --- a/src/services/api/graphql/graphql/queries.py +++ b/src/services/api/graphql/graphql/queries.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/libs/key_auth.py b/src/services/api/graphql/libs/key_auth.py index ffd7f32b2..dc3322fea 100644 --- a/src/services/api/graphql/libs/key_auth.py +++ b/src/services/api/graphql/libs/key_auth.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/libs/op_mode.py b/src/services/api/graphql/libs/op_mode.py index 86e38eae6..fa726264c 100644 --- a/src/services/api/graphql/libs/op_mode.py +++ b/src/services/api/graphql/libs/op_mode.py @@ -1,4 +1,4 @@ -# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/libs/token_auth.py b/src/services/api/graphql/libs/token_auth.py index 4f743a096..73c52bdf0 100644 --- a/src/services/api/graphql/libs/token_auth.py +++ b/src/services/api/graphql/libs/token_auth.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/routers.py b/src/services/api/graphql/routers.py index ed3ee1e8c..5526918d9 100644 --- a/src/services/api/graphql/routers.py +++ b/src/services/api/graphql/routers.py @@ -1,4 +1,4 @@ -# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/session/composite/system_status.py b/src/services/api/graphql/session/composite/system_status.py index 516a4eff6..1674b2c2b 100755 --- a/src/services/api/graphql/session/composite/system_status.py +++ b/src/services/api/graphql/session/composite/system_status.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/api/graphql/session/override/remove_firewall_address_group_members.py b/src/services/api/graphql/session/override/remove_firewall_address_group_members.py index b91932e14..9f39465a1 100644 --- a/src/services/api/graphql/session/override/remove_firewall_address_group_members.py +++ b/src/services/api/graphql/session/override/remove_firewall_address_group_members.py @@ -1,4 +1,4 @@ -# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/graphql/session/session.py b/src/services/api/graphql/session/session.py index 619534f43..e4725e752 100644 --- a/src/services/api/graphql/session/session.py +++ b/src/services/api/graphql/session/session.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/api/rest/models.py b/src/services/api/rest/models.py index dda50010f..70fab03ec 100644 --- a/src/services/api/rest/models.py +++ b/src/services/api/rest/models.py @@ -1,4 +1,4 @@ -# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,7 @@ from typing import Self  from pydantic import BaseModel  from pydantic import StrictStr +from pydantic import StrictInt  from pydantic import field_validator  from pydantic import model_validator  from fastapi.responses import HTMLResponse @@ -71,6 +72,8 @@ class BaseConfigureModel(BasePathModel):  class ConfigureModel(ApiModel, BaseConfigureModel): +    confirm_time: StrictInt = 0 +      class Config:          json_schema_extra = {              'example': { @@ -81,8 +84,12 @@ class ConfigureModel(ApiModel, BaseConfigureModel):          } +class ConfirmModel(ApiModel): +    op: StrictStr +  class ConfigureListModel(ApiModel):      commands: List[BaseConfigureModel] +    confirm_time: StrictInt = 0      class Config:          json_schema_extra = { @@ -134,13 +141,17 @@ class RetrieveModel(ApiModel):  class ConfigFileModel(ApiModel):      op: StrictStr      file: StrictStr = None +    string: StrictStr = None +    confirm_time: StrictInt = 0 +    destructive: bool = False      class Config:          json_schema_extra = {              'example': {                  'key': 'id_key', -                'op': 'save | load', +                'op': 'save | load | merge | confirm',                  'file': 'filename', +                'string': 'config_string'              }          } @@ -251,6 +262,20 @@ class RebootModel(ApiModel):          } +class RenewModel(ApiModel): +    op: StrictStr +    path: List[StrictStr] + +    class Config: +        json_schema_extra = { +            'example': { +                'key': 'id_key', +                'op': 'renew', +                'path': ['op', 'mode', 'path'], +            } +        } + +  class ResetModel(ApiModel):      op: StrictStr      path: List[StrictStr] diff --git a/src/services/api/rest/routers.py b/src/services/api/rest/routers.py index e52c77fda..329d6e51f 100644 --- a/src/services/api/rest/routers.py +++ b/src/services/api/rest/routers.py @@ -1,4 +1,4 @@ -# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public @@ -34,6 +34,7 @@ from fastapi import HTTPException  from fastapi import APIRouter  from fastapi import BackgroundTasks  from fastapi.routing import APIRoute +from fastapi.concurrency import run_in_threadpool  from starlette.datastructures import FormData  from starlette.formparsers import FormParser  from starlette.formparsers import MultiPartParser @@ -51,6 +52,7 @@ from .models import error  from .models import responses  from .models import ApiModel  from .models import ConfigureModel +from .models import ConfirmModel  from .models import ConfigureListModel  from .models import ConfigSectionModel  from .models import ConfigSectionListModel @@ -66,6 +68,7 @@ from .models import GenerateModel  from .models import ShowModel  from .models import RebootModel  from .models import ResetModel +from .models import RenewModel  from .models import ImportPkiModel  from .models import PoweroffModel  from .models import TracerouteModel @@ -301,8 +304,47 @@ def call_commit(s: SessionState):              LOG.warning(f'ConfigSessionError: {e}') -def _configure_op( +def call_commit_confirm(s: SessionState): +    env = s.session.get_session_env() +    env['IN_COMMIT_CONFIRM'] = 't' +    try: +        s.session.commit() +        s.session.commit_confirm(minutes=s.confirm_time) +    except ConfigSessionError as e: +        s.session.discard() +        if s.debug: +            LOG.warning(f'ConfigSessionError:\n {traceback.format_exc()}') +        else: +            LOG.warning(f'ConfigSessionError: {e}') +    finally: +        del env['IN_COMMIT_CONFIRM'] + + +def run_commit(s: SessionState): +    try: +        out = s.session.commit() +        return out, None +    except Exception as e: +        return None, e + + +def run_commit_confirm(s: SessionState): +    env = s.session.get_session_env() +    env['IN_COMMIT_CONFIRM'] = 't' +    try: +        out_c = s.session.commit() +        out_cc = s.session.commit_confirm(minutes=s.confirm_time) +        out = out_c + '\n' + out_cc +        return out, None +    except Exception as e: +        return None, e +    finally: +        del env['IN_COMMIT_CONFIRM'] + + +async def _configure_op(      data: Union[ +        ConfirmModel,          ConfigureModel,          ConfigureListModel,          ConfigSectionModel, @@ -319,6 +361,11 @@ def _configure_op(      session = state.session      env = session.get_session_env() +    # A non-zero confirm_time will start commit-confirm timer on commit +    confirm_time = 0 +    if isinstance(data, (ConfigureModel, ConfigureListModel, ConfigFileModel)): +        confirm_time = data.confirm_time +      # Allow users to pass just one command      if not isinstance(data, (ConfigureListModel, ConfigSectionListModel)):          data = [data] @@ -338,10 +385,16 @@ def _configure_op(      try:          for c in data:              op = c.op -            if not isinstance(c, BaseConfigSectionTreeModel): +            if not isinstance(c, (ConfirmModel, BaseConfigSectionTreeModel)):                  path = c.path -            if isinstance(c, BaseConfigureModel): +            if isinstance(c, ConfirmModel): +                if op == 'confirm': +                    msg = session.confirm() +                else: +                    raise ConfigSessionError(f"'{op}' is not a valid operation") + +            elif isinstance(c, BaseConfigureModel):                  if c.value:                      value = c.value                  else: @@ -387,16 +440,30 @@ def _configure_op(                  else:                      raise ConfigSessionError(f"'{op}' is not a valid operation")          # end for +          config = Config(session_env=env)          d = get_config_diff(config) -        if d.is_node_changed(['service', 'https']): -            background_tasks.add_task(call_commit, state) -            msg = self_ref_msg +        state.confirm_time = confirm_time if confirm_time else 0 + +        if not d.is_node_changed(['service', 'https']): +            if confirm_time: +                out, err = await run_in_threadpool(run_commit_confirm, state) +                if err: +                    raise err +                msg = msg + out if msg else out +            else: +                out, err = await run_in_threadpool(run_commit, state) +                if err: +                    raise err +                msg = msg + out if msg else out          else: -            # capture non-fatal warnings -            out = session.commit() -            msg = out if out else msg +            if confirm_time: +                background_tasks.add_task(call_commit_confirm, state) +            else: +                background_tasks.add_task(call_commit, state) +            out = self_ref_msg +            msg = msg + out if msg else out          LOG.info(f"Configuration modified via HTTP API using key '{state.id}'")      except ConfigSessionError as e: @@ -413,6 +480,8 @@ def _configure_op(          # Don't give the details away to the outer world          error_msg = 'An internal error occured. Check the logs for details.'      finally: +        if 'IN_COMMIT_CONFIRM' in env: +            del env['IN_COMMIT_CONFIRM']          lock.release()      if status != 200: @@ -431,12 +500,14 @@ def create_path_import_pki_no_prompt(path):  @router.post('/configure') -def configure_op( -    data: Union[ConfigureModel, ConfigureListModel], +async def configure_op( +    data: Union[ConfigureModel, ConfigureListModel, ConfirmModel],      request: Request,      background_tasks: BackgroundTasks,  ): -    return _configure_op(data, request, background_tasks) +    out = await _configure_op(data, request, background_tasks) + +    return out  @router.post('/configure-section') @@ -493,13 +564,18 @@ async def retrieve_op(data: RetrieveModel):  @router.post('/config-file') -def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks): +async def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):      state = SessionState()      session = state.session      env = session.get_session_env()      op = data.op      msg = None +    # A non-zero confirm_time will start commit-confirm timer on commit +    confirm_time = data.confirm_time + +    lock.acquire() +      try:          if op == 'save':              if data.file: @@ -507,22 +583,48 @@ def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):              else:                  path = '/config/config.boot'              msg = session.save_config(path) -        elif op == 'load': +        elif op in ('load', 'merge'):              if data.file:                  path = data.file +            elif data.string: +                path = '/tmp/config.file' +                with open(path, 'w') as f: +                    f.write(data.string)              else: -                return error(400, 'Missing required field "file"') +                return error(400, 'Missing required field "file | string"') -            session.migrate_and_load_config(path) +            match op: +                case 'load': +                    session.migrate_and_load_config(path) +                case 'merge': +                    session.merge_config(path, destructive=data.destructive)              config = Config(session_env=env)              d = get_config_diff(config) -            if d.is_node_changed(['service', 'https']): -                background_tasks.add_task(call_commit, state) -                msg = self_ref_msg +            state.confirm_time = confirm_time if confirm_time else 0 + +            if not d.is_node_changed(['service', 'https']): +                if confirm_time: +                    out, err = await run_in_threadpool(run_commit_confirm, state) +                    if err: +                        raise err +                    msg = msg + out if msg else out +                else: +                    out, err = await run_in_threadpool(run_commit, state) +                    if err: +                        raise err +                    msg = msg + out if msg else out              else: -                session.commit() +                if confirm_time: +                    background_tasks.add_task(call_commit_confirm, state) +                else: +                    background_tasks.add_task(call_commit, state) +                out = self_ref_msg +                msg = msg + out if msg else out + +        elif op == 'confirm': +            msg = session.confirm()          else:              return error(400, f"'{op}' is not a valid operation")      except ConfigSessionError as e: @@ -530,6 +632,10 @@ def config_file_op(data: ConfigFileModel, background_tasks: BackgroundTasks):      except Exception:          LOG.critical(traceback.format_exc())          return error(500, 'An internal error occured. Check the logs for details.') +    finally: +        if 'IN_COMMIT_CONFIRM' in env: +            del env['IN_COMMIT_CONFIRM'] +        lock.release()      return success(msg) @@ -657,6 +763,26 @@ def reboot_op(data: RebootModel):      return success(res) +@router.post('/renew') +def renew_op(data: RenewModel): +    state = SessionState() +    session = state.session + +    op = data.op +    path = data.path + +    try: +        if op == 'renew': +            res = session.renew(path) +        else: +            return error(400, f"'{op}' is not a valid operation") +    except ConfigSessionError as e: +        return error(400, str(e)) +    except Exception: +        LOG.critical(traceback.format_exc()) +        return error(500, 'An internal error occured. Check the logs for details.') + +    return success(res)  @router.post('/reset')  def reset_op(data: ResetModel): diff --git a/src/services/api/session.py b/src/services/api/session.py index ad3ef660c..c25a444e9 100644 --- a/src/services/api/session.py +++ b/src/services/api/session.py @@ -1,4 +1,4 @@ -# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This library is free software; you can redistribute it and/or  # modify it under the terms of the GNU Lesser General Public diff --git a/src/services/vyos-commitd b/src/services/vyos-commitd index e7f2d82c7..620d7eb6e 100755 --- a/src/services/vyos-commitd +++ b/src/services/vyos-commitd @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2025 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -42,6 +42,7 @@ from vyos.defaults import directories  from vyos.utils.boot import boot_configuration_complete  from vyos.configsource import ConfigSourceCache  from vyos.configsource import ConfigSourceError +from vyos.configdiff import get_commit_scripts  from vyos.config import Config  from vyos.frrender import FRRender  from vyos.frrender import get_frrender_dict @@ -230,6 +231,9 @@ def initialization(session: Session) -> Session:      dependent_func: dict[str, list[typing.Callable]] = {}      setattr(config, 'dependent_func', dependent_func) +    commit_scripts = get_commit_scripts(config) +    logger.debug(f'commit_scripts: {commit_scripts}') +      scripts_called = []      setattr(config, 'scripts_called', scripts_called) diff --git a/src/services/vyos-configd b/src/services/vyos-configd index 28acccd2c..22eb48102 100755 --- a/src/services/vyos-configd +++ b/src/services/vyos-configd @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2020-2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -68,6 +68,7 @@ class Response(Enum):      ERROR_COMMIT = 2      ERROR_DAEMON = 4      PASS = 8 +    ERROR_COMMIT_APPLY = 16  vyos_conf_scripts_dir = directories['conf_mode'] @@ -142,8 +143,6 @@ def run_script(script_name, config, args) -> tuple[Response, str]:      try:          c = script.get_config(config)          script.verify(c) -        script.generate(c) -        script.apply(c)      except ConfigError as e:          logger.error(e)          return Response.ERROR_COMMIT, str(e) @@ -152,6 +151,17 @@ def run_script(script_name, config, args) -> tuple[Response, str]:          logger.error(tb)          return Response.ERROR_COMMIT, tb +    try: +        script.generate(c) +        script.apply(c) +    except ConfigError as e: +        logger.error(e) +        return Response.ERROR_COMMIT_APPLY, str(e) +    except Exception: +        tb = traceback.format_exc() +        logger.error(tb) +        return Response.ERROR_COMMIT_APPLY, tb +      return Response.SUCCESS, '' diff --git a/src/services/vyos-conntrack-logger b/src/services/vyos-conntrack-logger index ec0e1f717..6e0733291 100755 --- a/src/services/vyos-conntrack-logger +++ b/src/services/vyos-conntrack-logger @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/vyos-domain-resolver b/src/services/vyos-domain-resolver index 4419fc4a7..17dae38e0 100755 --- a/src/services/vyos-domain-resolver +++ b/src/services/vyos-domain-resolver @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2022-2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -28,7 +28,7 @@ from vyos.utils.commit import commit_in_progress  from vyos.utils.dict import dict_search_args  from vyos.utils.kernel import WIREGUARD_REKEY_AFTER_TIME  from vyos.utils.file import makedir, chmod_775, write_file, read_file -from vyos.utils.network import is_valid_ipv4_address_or_range +from vyos.utils.network import is_valid_ipv4_address_or_range, is_valid_ipv6_address_or_range  from vyos.utils.process import cmd  from vyos.utils.process import run  from vyos.xml_ref import get_defaults @@ -143,10 +143,11 @@ def update_remote_group(config):          for set_name, remote_config in remote_groups.items():              if 'url' not in remote_config:                  continue -            nft_set_name = f'R_{set_name}' +            nft_ip_set_name = f'R_{set_name}' +            nft_ip6_set_name = f'R6_{set_name}'              # Create list file if necessary -            list_file = os.path.join(firewall_config_dir, f"{nft_set_name}.txt") +            list_file = os.path.join(firewall_config_dir, f"{nft_ip_set_name}.txt")              if not os.path.exists(list_file):                  write_file(list_file, '', user="root", group="vyattacfg", mode=0o644) @@ -159,16 +160,32 @@ def update_remote_group(config):              # Read list file              ip_list = [] +            ip6_list = [] +            invalid_list = []              for line in read_file(list_file).splitlines():                  line_first_word = line.strip().partition(' ')[0]                  if is_valid_ipv4_address_or_range(line_first_word):                      ip_list.append(line_first_word) +                elif is_valid_ipv6_address_or_range(line_first_word): +                    ip6_list.append(line_first_word) +                else: +                    if line_first_word[0].isalnum(): +                        invalid_list.append(line_first_word) -            # Load tables +            # Load ip tables              for table in ipv4_tables: -                if (table, nft_set_name) in valid_sets: -                    conf_lines += nft_output(table, nft_set_name, ip_list) +                if (table, nft_ip_set_name) in valid_sets: +                    conf_lines += nft_output(table, nft_ip_set_name, ip_list) + +            # Load ip6 tables +            for table in ipv6_tables: +                if (table, nft_ip6_set_name) in valid_sets: +                    conf_lines += nft_output(table, nft_ip6_set_name, ip6_list) + +            invalid_str = ", ".join(invalid_list) +            if invalid_str: +                logger.info(f'Invalid address for set {set_name}: {invalid_str}')              count += 1 diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd index 44f03586c..89742b431 100755 --- a/src/services/vyos-hostsd +++ b/src/services/vyos-hostsd @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2019-2023 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server index be3dd5051..c9d5f3a1b 100755 --- a/src/services/vyos-http-api-server +++ b/src/services/vyos-http-api-server @@ -1,6 +1,6 @@  #!/usr/share/vyos-http-api-tools/bin/python3  # -# Copyright (C) 2019-2024 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as diff --git a/src/services/vyos-network-event-logger b/src/services/vyos-network-event-logger index 840ff3cda..135cc8ec5 100644 --- a/src/services/vyos-network-event-logger +++ b/src/services/vyos-network-event-logger @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2025 VyOS maintainers and contributors +# Copyright VyOS maintainers and contributors <maintainers@vyos.io>  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as | 
