mirror of
https://github.com/dtzp555-max/aci-sim.git
synced 2026-07-21 21:15:12 +00:00
Initial public release — aci-sim v0.16.0
aci-sim is a stateful REST simulator of a 2-site Cisco ACI fabric (per-site APIC + ND/NDO management planes) — for testing ACI automation (Ansible cisco.aci / cisco.mso, aci-py, custom REST clients) and CI gates without real hardware. Highlights: APIC + NDO REST surface served from one in-memory MIT built from a declarative topology.yaml; port mode + sandbox (real per-device IPs on :443) run modes; LLDP/CDP neighbor visibility; NDO->APIC deploy mirror (multi-site templates materialize onto the target sites' APIC stores); real-APIC fvBD default attributes; file-backed state save/restore; an `aci-sim` CLI (validate/show/graph/run/new/init/lldp); and an 888-test suite. History squashed for the public release. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Orchestrator — assemble a full per-site MITStore from the topology.
|
||||
|
||||
Every sub-builder is a pure function of (topology, site) that only ADDS MOs and
|
||||
never reads another builder's output, so the order below is for readability only.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from aci_sim.build import (
|
||||
access,
|
||||
cabling,
|
||||
endpoints,
|
||||
fabric,
|
||||
health_faults,
|
||||
interfaces,
|
||||
l3out,
|
||||
mgmt,
|
||||
overlay,
|
||||
routing,
|
||||
tenants,
|
||||
underlay,
|
||||
userprofile,
|
||||
zoning,
|
||||
)
|
||||
from aci_sim.mit.store import MITStore
|
||||
from aci_sim.topology.schema import Site, Topology
|
||||
|
||||
# fabric first (nodes), then wiring/underlay/overlay, then tenant config,
|
||||
# then L3Out (needs border leaves), endpoints, and finally health/faults.
|
||||
#
|
||||
# Batch-1 note: `endpoints` now runs BEFORE `tenants` (moved from after
|
||||
# `l3out`) so tenants.py's fvRsPathAtt (static binding) can read back the
|
||||
# real fvCEp/fabricPathDn each EPG's endpoints already got from the store,
|
||||
# instead of re-deriving port assignment logic independently (which risked
|
||||
# silently drifting out of sync with endpoints.py). Every other builder
|
||||
# remains a pure "only ADDS MOs, never reads another builder's output"
|
||||
# function per the orchestrator's original contract — endpoints.py itself
|
||||
# still only adds and doesn't read from tenants/access/l3out, so moving it
|
||||
# earlier is safe (its only cross-module dependency, _HOST_PORTS, comes from
|
||||
# `interfaces`, which still runs first).
|
||||
#
|
||||
# Batch-2 note: `zoning` runs AFTER both `tenants` (needs fvAEPg.pcTag/
|
||||
# fvCtx.scope, and reuses tenants.py's pctag_for/scope_id_for helpers) and
|
||||
# `endpoints` (needs fvCEp to know which leaves host each EPG's local
|
||||
# endpoints) — same read-back pattern as tenants.py's fvRsPathAtt, so zoning
|
||||
# is placed right after tenants in the list (endpoints already ran earlier).
|
||||
# `overlay.build_vpn_routes` (bgpVpnRoute/bgpPath) has the same fvRsBd/fvCEp
|
||||
# read-back dependency, so it also runs post-tenants/endpoints — as a SECOND
|
||||
# call into the `overlay` module, alongside (not instead of) its early
|
||||
# `overlay.build` call which only needs fabric/topology data and stays in
|
||||
# its original early slot for BGP peer setup.
|
||||
#
|
||||
# OOB-gateway PR: `mgmt` builds the mgmt-tenant OOB scaffolding
|
||||
# (fvTenant(mgmt)/mgmtMgmtP/mgmtOoB/mgmtRsOoBStNode) that carries
|
||||
# site.oob_gateway on a real MO. It only needs topology data (site.all_nodes(),
|
||||
# oob_ip(), site.controller_oob_ips()) — no read-back from another builder's
|
||||
# store output — so, like every other builder here, it is placed for
|
||||
# readability only; it is grouped right after `fabric` since both build
|
||||
# node-identity/OOB data.
|
||||
_BUILDERS = [
|
||||
fabric,
|
||||
mgmt,
|
||||
cabling,
|
||||
underlay,
|
||||
overlay,
|
||||
interfaces,
|
||||
endpoints,
|
||||
tenants,
|
||||
zoning,
|
||||
access,
|
||||
l3out,
|
||||
routing,
|
||||
health_faults,
|
||||
userprofile,
|
||||
]
|
||||
|
||||
|
||||
def build_site(topo: Topology, site: Site) -> MITStore:
|
||||
"""Build and return a fully-populated MITStore for one site."""
|
||||
store = MITStore()
|
||||
for mod in _BUILDERS:
|
||||
mod.build(topo, site, store)
|
||||
overlay.build_vpn_routes(topo, site, store)
|
||||
return store
|
||||
|
||||
|
||||
def build_all(topo: Topology) -> dict[str, MITStore]:
|
||||
"""Build every site → ``{site_name: MITStore}``."""
|
||||
return {site.name: build_site(topo, site) for site in topo.sites}
|
||||
Reference in New Issue
Block a user