Skip to content

Feat(eos_designs): Add act_cv_instance to target a dev CV instance - #7312

Open
natedoot wants to merge 7 commits into
aristanetworks:develfrom
natedoot:feat/digital-twin-cv-instance
Open

Feat(eos_designs): Add act_cv_instance to target a dev CV instance#7312
natedoot wants to merge 7 commits into
aristanetworks:develfrom
natedoot:feat/digital-twin-cv-instance

Conversation

@natedoot

@natedoot natedoot commented Jul 30, 2026

Copy link
Copy Markdown

Allow users to specify a different CloudVision instance for Digital Twin deployment via digital_twin.fabric.act_cv_instance. In ACT Digital Twin mode, this overrides daemon_terminattr.cvaddrs so the digital twin connects to the dev/staging CV instance instead of production.

Fixes #6623

Change Summary

Add act_cv_instance option to digital_twin.fabric allowing users to target a specific CloudVision instance for Digital Twin deployment, separate from production.

Related Issue(s)

Fixes aristanetworks/avd#6623

Component(s) name

arista.avd.eos_designs

Proposed changes

Organizations running separate dev/staging and production CloudVision instances need the ability to point their Digital Twin to a non-production CV instance. This PR adds a new digital_twin.fabric.act_cv_instance key that:

  1. Overrides daemon_terminattr.cvaddrs in ACT Digital Twin mode, so the digital twin device connects to the specified CV instance instead of the production one defined in cv_settings.
  2. Passes the value through to metadata.digital_twin.cv_instance in the structured config output for downstream tooling consumption.

Data model:

eos_designs input

digital_twin:
fabric:
act_cv_instance: # e.g. "10.20.30.40:9910" or "cv-dev.example.com:443"

eos_cli_config_gen structured config output (metadata)

metadata:
digital_twin:
cv_instance:

The field is optional. When unset, behavior is unchanged — daemon_terminattr.cvaddrs uses the production addresses from cv_settings as before.

How to test

A dedicated molecule test host digital-twin-cv-instance-1 was added to the digital_twin scenario with:

  • Production CV: cv_settings.onprem_clusters[].servers[].name: 192.168.200.11
  • Digital Twin CV: digital_twin.fabric.act_cv_instance: 10.20.30.40:9910

Verified behavior:

  • Normal mode: daemon_terminattr.cvaddrs = 192.168.200.11:9910 (production)
  • Digital Twin mode: daemon_terminattr.cvaddrs = 10.20.30.40:9910 (dev) and metadata.digital_twin.cv_instance = 10.20.30.40:9910

Additionally, act_cv_instance was added to the existing digital-twin-enforce-eapi-1 host to verify metadata-only passthrough (no cv_settings / no daemon_terminattr).

All 8460 molecule scenario tests pass. Compiled schemas regenerated via pre-commit run schemas.

Repository Checklist

  • My code has been rebased from devel before I start
  • I have read the CONTRIBUTING document.
  • My change requires a change to the documentation and documentation have been updated accordingly.
  • I have updated molecule CI testing accordingly. (check the box if not applicable)

Summary by CodeRabbit

  • New Features
    • Added support for dedicated ACT Digital Twin CloudVision settings, including CVaaS, on-premises clusters, TerminAttr options, and source-interface behavior.
    • ACT Digital Twin devices now use the dedicated settings when configured.
    • Added a new Digital Twin test device with management connectivity, routing, NTP, and management API configuration.
  • Documentation
    • Documented the new ACT Digital Twin settings and added configuration examples.
    • Added the new device to topology and fabric documentation.

@natedoot
natedoot requested review from a team as code owners July 30, 2026 17:10
@github-actions

Copy link
Copy Markdown

Review docs on Read the Docs

To test this pull request:

# Create virtual environment for this testing below the current directory
python -m venv test-avd-pr-7312
# Activate the virtual environment
source test-avd-pr-7312/bin/activate
# Install all requirements including PyAVD
pip install "pyavd[ansible] @ git+https://github.com/natedoot/avd.git@feat/digital-twin-cv-instance#subdirectory=python-avd" --force
# Point Ansible collections path to the Python virtual environment
export ANSIBLE_COLLECTIONS_PATH=$VIRTUAL_ENV/ansible_collections
# Install Ansible collection
python -m ansible.cli.galaxy collection install git+https://github.com/natedoot/avd.git#/ansible_collections/arista/avd/,feat/digital-twin-cv-instance --force
cd test-avd-pr-7312
# Run your playbook using `python -m ansible.cli.playbook path/to/playbook.yml ...`

You can also test this PR using AVD playground:

  • Rebase your branch to makes sure it is up-to-date and has latest lab topologies for example inventories
  • Authenticate on labs.arista.com. Use your email! Not login.
  • Start the playground
  • In the lab selector UI pick "I want to use a specific AVD fork"
  • Enter following parameters:
GitHub org: natedoot
Repository name: avd
Branch: feat/digital-twin-cv-instance
  • Select an example inventory to test the PR
  • Once the AVD Playground setup will be finished, type make start and test anything once the lab is up

@github-actions github-actions Bot added role: eos_cli_config_gen issue related to eos_cli_config_gen role state: CI Updated CI scenario have been updated in the PR state: Documentation role Updated role: eos_designs issue related to eos_designs role labels Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds digital_twin.fabric.act_cv_settings to the eos_designs schema and typed models. ACT Digital Twin configurations use these settings for TerminAttr. A new Digital Twin CV instance fixture includes topology, inventory, generated configuration, and documentation.

Changes

Digital Twin ACT CloudVision settings

Layer / File(s) Summary
ACT CloudVision configuration contracts
python-avd/pyavd/_eos_designs/schema/..., ansible_collections/arista/avd/roles/eos_designs/docs/tables/cloudvision-settings.md
Adds the act_cv_settings schema field, typed models, initializer support, and documentation.
ACT CloudVision runtime targeting
python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py
Uses ACT-specific CloudVision settings instead of standard cv_settings when ACT Digital Twin mode is active.
Digital Twin CV instance fixture
ansible_collections/arista/avd/extensions/molecule/digital_twin/.../topology.yml, .../inventory/...
Adds digital-twin-cv-instance-1, its management settings, ACT dev cluster, fallback production cluster, and NTP configuration.
Generated configuration and documentation
ansible_collections/arista/avd/extensions/molecule/digital_twin/.../intended/..., .../documentation/...
Adds structured configuration, EOS configuration, topology documentation, management IP, and provisioned status for the new instance.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FabricActCvSettings
  participant DaemonTerminattr
  participant TerminAttr
  FabricActCvSettings->>DaemonTerminattr: provide ACT CloudVision settings
  DaemonTerminattr->>DaemonTerminattr: replace standard cv_settings
  DaemonTerminattr->>TerminAttr: generate ACT-specific connection settings
Loading

Possibly related PRs

Suggested labels: rn: Feat(eos_designs)

Suggested reviewers: joelbreton2, alexeygorbunov, maheshgslab

Poem

I’m a rabbit with a twin in the cloud,
ACT settings make my paths clear and proud.
Dev gets the carrots, production stays near,
TerminAttr hops to the cluster it hears.
New configs bloom—thump, thump, hooray! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title identifies the Digital Twin CloudVision targeting change, although it uses the superseded act_cv_instance name instead of act_cv_settings.
Description check ✅ Passed The description includes the required sections, linked issue, proposed changes, data model, testing details, and completed repository checklist.
Linked Issues check ✅ Passed The changes satisfy issue #6623 by allowing ACT Digital Twin deployments to target a separate CloudVision instance through act_cv_settings.
Out of Scope Changes check ✅ Passed Documentation, schema, implementation, generated configuration, and molecule coverage directly support the Digital Twin CloudVision targeting objective.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@ansible_collections/arista/avd/extensions/molecule/digital_twin/intended/configs/digital-twin-cv-instance-1.cfg`:
- Around line 5-6: Regenerate the Digital Twin expected artifacts so the
TerminAttr command in
ansible_collections/arista/avd/extensions/molecule/digital_twin/intended/configs/digital-twin-cv-instance-1.cfg
uses the intended 10.20.30.40:9910 CV address and removes the stale
127.0.0.1:9911 reference. Keep the existing structured config values in
ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml
at lines 4-6 and 31-33 unchanged, and leave the matching documentation entries
in
ansible_collections/arista/avd/extensions/molecule/digital_twin/documentation/fabric/DIGITAL_TWIN-documentation.md
lines 18-25 unchanged.

In
`@ansible_collections/arista/avd/extensions/molecule/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml`:
- Around line 31-33: Add the expected alternate Digital Twin CloudVision
instance under the fixture's metadata.digital_twin.cv_instance structure,
alongside the existing is_deployed and fabric_name metadata. Use the overridden
daemon_terminattr.cvaddrs value so this intended structured configuration
validates metadata propagation.

In `@python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py`:
- Around line 69-75: Normalize the shared act_cv_instance value before assigning
it to TerminAttr cvaddrs, converting URL-form inputs to the accepted host/port
format or rejecting them consistently. Apply this to both daemon_terminattr.py
ranges 69-75 and 89-91, preserving get_cv_addrs behavior for non-ACT clusters;
update the digital-twin-enforce-eapi-1.yml range 15 fixture if needed to cover
the normalized or rejected URL input.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 986d783b-6071-482a-a105-807ee6fd580c

📥 Commits

Reviewing files that changed from the base of the PR and between 560b92c and 325ee8d.

📒 Files selected for processing (21)
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/documentation/fabric/DIGITAL_TWIN-documentation.md
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/documentation/fabric/DIGITAL_TWIN-topology.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/configs/digital-twin-cv-instance-1.cfg
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/structured_configs/digital-twin-enforce-eapi-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/documentation/fabric/DIGITAL_TWIN-documentation.md
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/intended/configs/digital-twin-cv-instance-1.cfg
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/inventory/host_vars/digital-twin-cv-instance-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/inventory/host_vars/digital-twin-enforce-eapi-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/inventory/hosts.yml
  • ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/metadata.md
  • ansible_collections/arista/avd/roles/eos_designs/docs/tables/digital-twin-configuration.md
  • python-avd/pyavd/_eos_cli_config_gen/schema/__init__.py
  • python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml
  • python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/metadata.schema.yml
  • python-avd/pyavd/_eos_designs/schema/__init__.py
  • python-avd/pyavd/_eos_designs/schema/eos_designs.schema.yml
  • python-avd/pyavd/_eos_designs/schema/schema_fragments/digital_twin.schema.yml
  • python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py
  • python-avd/pyavd/_eos_designs/structured_config/metadata/digital_twin.py

Comment thread python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py Outdated
@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.88%. Comparing base (1f4748d) to head (fa23ecf).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            devel    #7312   +/-   ##
=======================================
  Coverage   92.87%   92.88%           
=======================================
  Files         783      783           
  Lines       43363    43366    +3     
  Branches    10541    10542    +1     
=======================================
+ Hits        40273    40279    +6     
+ Misses       1886     1885    -1     
+ Partials     1204     1202    -2     
Components Coverage Δ
pyavd 94.58% <100.00%> (+<0.01%) ⬆️
schema_tools 68.79% <ø> (ø)
Ansible plugins 79.89% <ø> (ø)
Files with missing lines Coverage Δ
...esigns/structured_config/base/daemon_terminattr.py 93.54% <100.00%> (+3.54%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ClausHolbechArista ClausHolbechArista left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cv_instance is a deprecated or maybe even removed key by now. We should not reintroduce this model. Please reimplement this with a pattern that resembles the cv_settings schema. Maybe it is even a full act_cv_settings: under the digital twin, where we just read that instead of the global cv_settings.

@natedoot

natedoot commented Aug 7, 2026

Copy link
Copy Markdown
Author

cv_instance is a deprecated or maybe even removed key by now. We should not reintroduce this model. Please reimplement this with a pattern that resembles the cv_settings schema. Maybe it is even a full act_cv_settings: under the digital twin, where we just read that instead of the global cv_settings.

Thanks for the feedback Claus. I want to confirm the intended structure. A couple of questions:

  1. Placement — where should act_cv_settings live?

Option A — sibling to fabric under digital_twin:

  fabric:
    act_username: cvpadmin
    # ...
  act_cv_settings:
    onprem_clusters:
      - name: dev
        servers:
          - name: 10.20.30.40

Option B — under digital_twin.fabric alongside the other act_* keys:

  fabric:
    act_username: cvpadmin
    act_cv_settings:
      onprem_clusters:
        - name: dev
          servers:
            - name: 10.20.30.40
  1. Schema reuse — should act_cv_settings reference cv_settings via $ref, or define its own subset of keys?

Using $ref would inherit the full cv_settings key tree automatically:

  type: dict
  $ref: "eos_designs#/keys/cv_settings"
  description: |-
    CloudVision settings for ACT Digital Twin deployment.
    When set, overrides cv_settings for devices in ACT Digital Twin mode.

This keeps both schemas in sync, but also pulls in keys that may not be relevant in the digital twin context (e.g., set_source_interfaces, terminattr sub-settings). Alternatively, a trimmed subset would cherry-pick only the relevant sub-keys:

  type: dict
  keys:
    cvaas:
      $ref: "eos_designs#/keys/cv_settings/keys/cvaas"
    onprem_clusters:
      $ref: "eos_designs#/keys/cv_settings/keys/onprem_clusters"
  1. Behavior — when act_cv_settings is defined in DT mode, should it fully replace cv_settings for daemon_terminattr generation, or only override cvaddrs?

…on instance for Digital Twin

Allow users to specify a different CloudVision instance for Digital Twin
deployment via `digital_twin.fabric.act_cv_instance`. In ACT Digital Twin
mode, this overrides `daemon_terminattr.cvaddrs` so the digital twin
connects to the dev/staging CV instance instead of production.

Fixes aristanetworks#6623
@natedoot
natedoot force-pushed the feat/digital-twin-cv-instance branch from e7ec542 to a014acd Compare August 10, 2026 17:46
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

…cv_settings

Addresses maintainer feedback on PR aristanetworks#7312. Replaces the flat
`act_cv_instance` string with a structured `act_cv_settings` block
under `digital_twin.fabric` that inherits the full `cv_settings` schema
via `$ref`. When set in ACT Digital Twin mode, `act_cv_settings` fully
replaces `cv_settings` for `daemon_terminattr` generation, giving users
control over clusters, auth, VRF, and all terminattr settings.
@github-actions github-actions Bot removed the role: eos_cli_config_gen issue related to eos_cli_config_gen role label Aug 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py`:
- Around line 37-40: Update the cv_settings selection in the daemon_terminattr
configuration method so ACT Digital Twin mode chooses
digital_twin.fabric.act_cv_settings before the guard that returns when global
cv_settings is unset. Preserve the existing global cv_settings fallback for
non-ACT configurations, and add a test covering an ACT-only configuration that
generates daemon_terminattr without top-level cv_settings.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d14205d1-14cb-420a-9699-8b2a8df60ea5

📥 Commits

Reviewing files that changed from the base of the PR and between a014acd and b3cfc3f.

📒 Files selected for processing (7)
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/inventory/host_vars/digital-twin-cv-instance-1.yml
  • ansible_collections/arista/avd/roles/eos_designs/docs/tables/cloudvision-settings.md
  • python-avd/pyavd/_eos_designs/schema/__init__.py
  • python-avd/pyavd/_eos_designs/schema/eos_designs.schema.yml
  • python-avd/pyavd/_eos_designs/schema/schema_fragments/digital_twin.schema.yml
  • python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py
💤 Files with no reviewable changes (1)
  • ansible_collections/arista/avd/extensions/molecule/digital_twin/digital_twin/intended/structured_configs/digital-twin-cv-instance-1.yml

Comment thread python-avd/pyavd/_eos_designs/structured_config/base/daemon_terminattr.py Outdated
Move act_cv_settings override before the cv_settings early-return guard
so that act_cv_settings works even when global cv_settings is not set.
Add missing device documentation files for digital-twin-cv-instance-1.
@natedoot

Copy link
Copy Markdown
Author

What I ended up changing:

  1. Replaced act_cv_instance (flat string) with act_cv_settings (structured dict) under digital_twin.fabric. It uses $ref: "eos_designs#/keys/cv_settings" to inherit the full cv_settings schema — cvaas, onprem_clusters, terminattr, and set_source_interfaces — so users configure their DT CloudVision
    connection the same way they configure production.
  2. Full substitution instead of partial override. In daemon_terminattr.py, when in ACT Digital Twin mode and act_cv_settings is set, it replaces cv_settings entirely (cast via _cast_as). This means the DT config gets its own clusters, auth method, token file, VRF — not just a different address.
  3. Removed cv_instance from the output metadata schema since the CV targeting is now expressed through daemon_terminattr configuration, not a metadata field.
  4. Normal-mode configs are unaffected. The override only activates when is_act_digital_twin is True (the digital-twin scenario run), so production configs in intended/ continue using global cv_settings.

@ClausHolbechArista

Copy link
Copy Markdown
Contributor

Perfect. Thank you for this. I agree on everything you have done to address my comment. One more thing though, instead of act_cv_settings, this shold probably just be cv_settings as it will be no different for other digital-twin platforms. We should only need the act_ prefix when it is something specific for that platform.

@natedoot

Copy link
Copy Markdown
Author

Perfect. Thank you for this. I agree on everything you have done to address my comment. One more thing though, instead of act_cv_settings, this shold probably just be cv_settings as it will be no different for other digital-twin platforms. We should only need the act_ prefix when it is something specific for that platform.

I was thinking the same. I'll adjust and resubmit once ready for review.

natedoot and others added 3 commits August 19, 2026 15:09
…bric

Per maintainer feedback, cv_settings is platform-agnostic and does not
need the act_ prefix. Only settings specific to a digital twin platform
(e.g., act_os_version, act_node_type) use the platform prefix.

Also includes upstream doc formatting updates (False -> false in IPv6
routing summary tables).
@sonarqubecloud

Copy link
Copy Markdown

@natedoot

Copy link
Copy Markdown
Author

All set - here's what changed:

Renamed act_cv_settings to cv_settings under digital_twin.fabric since CloudVision settings are platform-agnostic and don't need the act_ prefix.

 digital_twin:
   fabric:
     cv_settings:
       type: dict
       $ref: "eos_designs#/keys/cv_settings"

Inherits the full cv_settings key tree via $ref — cvaas, onprem_clusters, terminattr, set_source_interfaces.

Behavior (daemon_terminattr.py): When in Digital Twin mode and digital_twin.fabric.cv_settings is set, it fully replaces the global cv_settings for daemon_terminattr generation. All downstream logic (clusters, auth, VRF, terminattr settings) works unchanged.

User-facing config:

cv_settings:
  onprem_clusters:
    - name: production
      servers:
        - name: 192.168.200.11      

# Digital twin override (used only for DT configs)
digital_twin:
  fabric:
    cv_settings:
      onprem_clusters:
        - name: dev
          servers:
            - name: 10.20.30.40

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

Labels

role: eos_designs issue related to eos_designs role state: CI Updated CI scenario have been updated in the PR state: Documentation role Updated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Digital Twin - Option for CloudVision instance

2 participants