Skip to content

Added concurrent update and hybrid scanning settings to agent_config.edit - #1043

Merged
SteveMcGrath merged 3 commits into
tenable:mainfrom
lanz:RDC-25175-agent-config-options
Oct 12, 2026
Merged

SteveMcGrath merged 3 commits into
tenable:mainfrom
lanz:RDC-25175-agent-config-options

Conversation

@lanz

@lanz lanz commented Oct 4, 2026

Copy link
Copy Markdown
Member

Description

This adds the documented concurrent_update and hybrid_scanning_enabled settings of PUT /scanners/null/agents/config to tio.agent_config.edit(). concurrent_update was announced in Concurrent Update Settings for Sensor Configurations (2026-01-27). This PR also fixes the module's two :devportal: links, which pointed at each other's pages.

Commit Change
Corrected swapped developer portal links in agent_config edit() now links to agent-config-edit, and details() to agent-config-details.
Added concurrent update and hybrid scanning settings to agent_config.edit New keyword-only arguments: concurrent_update (bool), max_concurrent_update (int, 0–2500) and hybrid_scanning_enabled (bool).

Design notes:

  • Two arguments for concurrent updates. max_concurrent_update is separate from the concurrent_update switch, because 0 is a valid limit: it stops agents from updating plugins. The single-integer style of auto_unlink would read 0 as "disable".
  • Only what's passed is sent. Live testing showed that the API merges a partial body into the existing configuration, including inside concurrent_update. So edit(max_concurrent_update=0) changes only the limit, and the docstring says unspecified settings keep their values.
  • Validation. max_concurrent_update must be an int, not bool, from 0 to 2500, checked before the request is sent. The booleans use the module's existing _check().
  • Unchanged behavior. With the new arguments omitted, the request body is exactly as before, including the existing empty auto_unlink object, which the API ignores.

No new dependencies. CHANGELOG.md and tenable/version.py are untouched.

Fixes #1042

Internal tracking: RDC-25175.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Unit tests. They use responses and add no cassettes. They assert the exact request body with json_params_matcher(..., strict_match=True).

  • Request bodies:
    • each new argument on its own, and both concurrent-update arguments together;
    • max_concurrent_update at 0 and 2500;
    • all five settings at once, together with the existing software_update and auto_unlink;
    • no arguments, which produces the previous body.
  • Rejected values: max_concurrent_update of 2501 or -1 raises UnexpectedValueError. A string or bool raises TypeError. Invalid booleans raise TypeError. None of these sends a request.
  • Keyword-only: the new arguments can't be passed positionally.
  • Fail on main: every test that sends a new value, and both range checks, fail against main. The no-arguments case passes there because the request is unchanged.
  • Per commit: each commit's lint and agent config tests pass with only that commit checked out.
  • Lint and suite: ruff check tenable is clean, and ruff format reports no changes in agent_config.py. The full suite passes on 3.11, 3.12, 3.13 and 3.14: 2190 passed, 0 failed, 95.6–95.8% coverage, and no new cassettes.
  • Bandit: bandit -ll results are unchanged from main (no medium or high issues).
  • Docs: the Sphinx build is unchanged from main (the same 6 warnings). The new arguments render, and both reference links point to the right pages.

Live API tests. These used the patched methods against three Tenable Vulnerability Management test environments. The agent configuration is a single account-wide setting, so each test recorded the original configuration first, restored it in a finally block, and verified the restored configuration was identical. All 15 checks passed in each environment:

  • Limit: edit(concurrent_update=True, max_concurrent_update=123) applied both values and left every other setting unchanged. The response matched details().
  • One key at a time:
    • edit(max_concurrent_update=0) kept enabled=True;
    • edit(concurrent_update=False) kept the limit of 0.
  • Hybrid scanning: edit(hybrid_scanning_enabled=...) toggled the setting both ways without touching concurrent_update.
  • Unchanged config: edit() with no arguments, and with only the existing software_update argument, left the configuration as it was.
  • Local rejections: out-of-range and string limits were rejected locally, and the configuration was unchanged.
  • Restore through edit(): passing the original values to edit() reproduced the original configuration exactly.
  • Agent behavior not observed. The test environments' agents were all offline, so these tests confirm the API contract only. They don't show agents actually limiting plugin updates or running hybrid scans.

Test Configuration:

  • Python Version(s) Tested: 3.11.16, 3.12.14, 3.13.15, 3.14.7 (Windows 11)
  • Tenable.sc version (if necessary): N/A

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules (none required)

lanz added 2 commits October 3, 2026 21:33
The edit() docstring linked to the agent-config-details reference page and
details() linked to agent-config-edit. Each now links to its own page.
…edit (RDC-25175)

agent_config.edit() now accepts keyword-only concurrent_update,
max_concurrent_update and hybrid_scanning_enabled arguments, sent in the
agent-config-edit request body. max_concurrent_update is validated as an
integer from 0 to 2500 before the request is sent, and the booleans are
validated with _check().

Only the settings passed are sent. Live testing showed that the API
merges a partial body into the existing configuration, including the
nested concurrent_update object, so omitted settings keep their values;
the docstring says so.
@lanz
lanz requested a review from a team as a code owner October 4, 2026 05:40
@SteveMcGrath
SteveMcGrath merged commit ff91591 into tenable:main Oct 12, 2026
8 of 9 checks passed
@varap11

varap11 commented Oct 13, 2026 via email

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Support concurrent update and hybrid scanning settings in tio.agent_config.edit()

3 participants