Skip to content

Add nd analyze to trigger an assurance analysis on demand - #5

Open
noppanut15 wants to merge 1 commit into
netascode:mainfrom
noppanut15:analyze-command
Open

Add nd analyze to trigger an assurance analysis on demand#5
noppanut15 wants to merge 1 commit into
netascode:mainfrom
noppanut15:analyze-command

Conversation

@noppanut15

@noppanut15 noppanut15 commented Aug 14, 2026

Copy link
Copy Markdown

Add nd analyze: trigger an assurance analysis on demand

Why

Nexus Dashboard collects online fabrics on its own schedule, depending on fabric size. A pipeline that pins snapshots latest before a change and compares against latest afterwards races that schedule: if no collection happened in between, both selectors resolve to the same record and delta reports nothing.

This repo has been read-only with respect to snapshots — snapshots resolves latest / latest-N / an explicit ID out of what already exists, and nothing asks ND to collect one.

What

nac-analytics nd analyze posts to POST /api/v1/analyze/jobs/assuranceAnalysis, waits for the resulting snapshot and prints its ID, so a configuration push can be bracketed by two real snapshots. Here is an example use case:

PRE=$(nac-analytics nd analyze)
terraform apply plan.tfplan
POST=$(nac-analytics nd analyze)
nac-analytics nd delta "$PRE" "$POST"

--no-wait prints the analysis job ID instead and skips all polling; its help text says plainly that this is not a snapshot ID and cannot be passed to delta. -o json|yaml emits the whole snapshot record, including the analysisJobId that ties it back to the trigger.

Unlike snapshots, this command takes real --timeout / --poll-interval values (ND_JOB_TIMEOUT_MINUTES / ND_POLL_INTERVAL), since collection time scales with fabric size. No new configuration settings: the request body carries only the fabric name, which already flows through --fabric / ND_FABRIC.

Changes

File
products/nexus_dashboard/client.py trigger_assurance_analysis(), wait_for_analysis_snapshot(), latest_collection_timestamp(); pure helpers analysis_job_id(), snapshot_for_job(), snapshot_newer_than(); ANALYSIS_SUCCEEDED / ANALYSIS_FAILED
products/nexus_dashboard/cli.py the analyze command; _emit_notices() (also now used by snapshots) and _analysis_trigger_error()
tests/unit/test_analyze.py 23 tests, new file
docs/ new commands/nexus-dashboard/analyze.md; verb tables in commands/README.md, commands/nexus-dashboard/README.md, nexus-dashboard.md; cross-reference from snapshots.md

No new exit codes: trigger failure → 1 (ApiError) or 5 (AuthError), timeout / missing job ID / failed job → 2 (JobError), bad input → 4.

Testing

ruff check, ruff format --check, mypy (24 source files) and pytest (218 passed) all clean.

The 23 new tests cover the trigger body and job-ID parsing, ID matching (including the shared-job-ID and stale-baseline cases), every job status branch, the absence window for a job /jobs/summary never reports, the timeout, the unmatched-snapshot warning, and four end-to-end CLI runs — text output, JSON output, --no-wait issuing no polling at all, and a 403 naming the roles.

Verified against a live ND 4.2.1 cluster before implementation: the returned jobId reappears verbatim as the snapshot's analysisJobId, and the status path is SCHEDULED → RUNNING → COMPLETE.

Nexus Dashboard collects online fabrics every 2-4 hours, so a pipeline that
pins `snapshots latest` before a change and compares against `latest` after
can resolve both selectors to the same record and see no delta at all.

`nd analyze` posts to /api/v1/analyze/jobs/assuranceAnalysis, waits for the
job, and prints the ID of the snapshot it produced, so a push can be
bracketed by two real snapshots.

The wait is two-phase because no snapshot is visible until the job is
terminal: the job is polled first (by ID only -- jobType varies between
ONLINE-ANALYSIS, -ACI and -NX), then the snapshot list. A failed job reports
the API's own errorMessage rather than timing out silently.

Matching a job to its snapshot needs both an analysisJobId match and a
collectionTimestamp newer than the pre-trigger baseline. analysisJobId is not
unique -- the recurring scheduled analysis keeps one ID across cycles -- so
the newest match wins, and a snapshot that already existed can never be
reported as this run's result.

Triggering requires the super-admin, fabric-admin or support-engineer role;
an observer account is refused with HTTP 403, which surfaces as an AuthError
naming the roles. --no-wait prints the job ID instead, and its help says
plainly that this is not a snapshot ID.

Verified against a live ND 4.2.1 cluster: the returned jobId reappears
verbatim as the snapshot's analysisJobId, and the status path is
SCHEDULED -> RUNNING -> COMPLETE.
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.

1 participant