Skip to content

Capirca configuration generation will crash if address object starts with a number #319

@loulecrivain

Description

@loulecrivain

Environment

  • Python version: 3.11.9
  • Nautobot version: 2.3.1
  • nautobot-firewall-models version: 2.2.2 (latest release as of 21-08-2025)

Expected Behavior

It is expected that following request of the " Generate FW Config via Capirca.", with a policy rule containing an address object with a name starting with a number, firewall configuration generation by the backend should take place and the job should succeed.

Observed Behavior

The job halts with a "Failed" status and produces the following error:

{
    "exc_message": [
        " ERROR on \"1020016\" (type INTEGER, line 8, Next '-')"
    ],
    "exc_module": "capirca.lib.policy",
    "exc_type": "ParseError"
} 

Steps to Reproduce

  1. Create a platform with a network driver known by Capirca (here I am using palo alto since ZBFs are easier to setup w no custom fields but it does not matter, as the bug will happen with any supported generator)
  2. Assign platform to pre-existing target Device
  3. Inside the firewall models app: create an address object with the following name: "10.200/16 VM global network"
  4. Create a test policy and assign it to target Device
  5. Create a policy rule with the address object attached and insert it into the test policy

I believe this is due to the custom slugify not being sufficient for Capirca .pol YACC parser restrictions and/or missing escape/quotes somewhere in the glue code with Capirca.

Image

Full celery worker stack trace

worker-1    | [2025-08-21 20:26:21,396: DEBUG/ForkPoolWorker-6] Parsing Service List
worker-1    | [2025-08-21 20:26:21,396: DEBUG/ForkPoolWorker-6] Parsing Network List
worker-1    | [2025-08-21 20:26:21,396: DEBUG/ForkPoolWorker-6] Parsing Policy
worker-1    | [2025-08-21 20:26:21,431: ERROR/ForkPoolWorker-6] Task nautobot.extras.jobs.run_job[7938b5f0-3180-49fb-b4aa-1cbcaa05f249] raised unexpected: ParseError(' ERROR on "1020016" (type INTEGER, line 8, Next \'-\')')
worker-1    | Traceback (most recent call last):
worker-1    |   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 477, in trace_task
worker-1    |     R = retval = fun(*args, **kwargs)
worker-1    |                  ^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 760, in __protected_call__
worker-1    |     return self.run(*args, **kwargs)
worker-1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/nautobot/extras/jobs.py", line 1136, in run_job
worker-1    |     result = job(*args, **kwargs)
worker-1    |              ^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/nautobot/extras/jobs.py", line 149, in __call__
worker-1    |     return self.run(*args, **deserialized_kwargs)
worker-1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/source/nautobot_firewall_models/jobs.py", line 51, in run
worker-1    |     CapircaPolicy.objects.update_or_create(device=device_obj)
worker-1    |   File "/usr/local/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
worker-1    |     return getattr(self.get_queryset(), name)(*args, **kwargs)
worker-1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 970, in update_or_create
worker-1    |     obj.save(using=self.db, update_fields=update_fields)
worker-1    |   File "/source/nautobot_firewall_models/models/capirca_policy.py", line 55, in save
worker-1    |     cap_obj.get_all_capirca_cfg()
worker-1    |   File "/source/nautobot_firewall_models/utils/capirca.py", line 613, in get_all_capirca_cfg
worker-1    |     self.get_capirca_cfg()
worker-1    |   File "/source/nautobot_firewall_models/utils/capirca.py", line 576, in get_capirca_cfg
worker-1    |     self.cfg_file = generate_capirca_config(servicecfg, networkcfg, self.pol_file, self.platform)
worker-1    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/source/nautobot_firewall_models/utils/capirca.py", line 81, in generate_capirca_config
worker-1    |     pol = policy.ParsePolicy(pol, defs, optimize=True)
worker-1    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/capirca/lib/policy.py", line 2747, in ParsePolicy
worker-1    |     policy = parser.parse(preprocessed_data, lexer=lexer)
worker-1    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/ply/yacc.py", line 333, in parse
worker-1    |     return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
worker-1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/ply/yacc.py", line 1201, in parseopt_notrack
worker-1    |     tok = call_errorfunc(self.errorfunc, errtoken, self)
worker-1    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/ply/yacc.py", line 192, in call_errorfunc
worker-1    |     r = errorfunc(token)
worker-1    |         ^^^^^^^^^^^^^^^^
worker-1    |   File "/usr/local/lib/python3.11/site-packages/capirca/lib/policy.py", line 2599, in p_error
worker-1    |     raise ParseError(' ERROR on "%s" (type %s, line %d, Next %s)'
worker-1    | capirca.lib.policy.ParseError:  ERROR on "1020016" (type INTEGER, line 8, Next '-')

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions