Design¶
vsc builds its command tree by statically introspecting the installed
vcf-sdk vAPI bindings. Both vmware-vcenter and vcf-nsx are vAPI stub
libraries on the shared vmware-vapi-runtime:
- Each service is a
VapiInterfacesubclass (VM,Host,Cluster,Datastore,Network, …). - Every operation carries
OperationRestMetadata(http_method,path_variables,query_parameters). - Parameters are typed via
StructTypebinding types.
A single generator walks those classes and emits one Typer command per
operation. http_method == "GET" ⇒ a read command; other verbs ⇒ writes
(dry-run by default + --apply). Because the metadata ships inside the SDK, the
tree builds offline — no server needed to render --help.
Top-level grouping:
vsc vsphere …→com.vmware.vcenter(+ selectedcom.vmware.esx)vsc nsx …→vcf.nsx.policy(NSX Policy API)
The introspected intermediate representation is a list of Operation objects,
each carrying typed Params (vsc/gen/model.py). Everything below is built from
that one model.
Ergonomics (v0.3)¶
These build on the introspected Param model without changing the agent
contract.
Offline shell completion¶
Completion values come entirely from the model and local config — never a
network call, so <TAB> stays fast and --help stays offline. Enum options
complete from their fixed choices, --output from the output formats, and
--profile from configured profile names (vsc/gen/complete.py). Completing a
live resource id would require a connection and is deferred to a later release.
Per-field filter flags¶
A list operation takes a single filter parameter that is a struct
(VM.FilterSpec etc.). The generator flattens that struct into typed
--<field> options (repeatable for list/set fields; enum fields validate and
complete their choices). The raw --filter '<json>' blob remains as a base
layer that per-field flags merge over (vsc/gen/filters.py).
Pagination¶
list commands gain --all (follow the NSX cursor across pages), --max-items
(cap the total), and --limit (client-side cap for non-paginated vSphere
lists). Without --all, a paginated list returns one page and surfaces its
cursor for manual paging; on non-cursor backends --all is a no-op and the
output stays a plain array (vsc/gen/paginate.py).
pyVmomi fallback (v0.3)¶
A few inventory/performance areas are only reachable through the older pyVmomi
SOAP API. Those are hand-written read-only commands mounted under
vsc vsphere alongside the generated ones, sharing the same output contract:
- a separate connection path,
connect_vmomi()viaSmartConnect, reusing the resolved vSphere credentials and honouring--insecurelike the REST path (vsc/connect/vmomi.py); vmomi_jsonable()collapses managed objects to their moref and data objects to dicts so results render like any other;- a shared
run_read()runner maps pyVmomi faults onto the same error envelope and exit codes (vsc/pyvmomi/runner.py).
Commands: perf (PerformanceManager counters), events / tasks
(Event/Task managers), and inventory — a PropertyCollector property walk
(inventory vm/host) plus inventory find, which sweeps every VM's guest.*
properties in one round-trip to locate a VM by IP / name / hostname / MAC / guest
OS / power state (the fields the REST vm list filter can't reach). All are
reads — no --apply.
Design specs¶
The authoritative, milestone-by-milestone designs live in the repository:
Contracts¶
- Output: JSON by default;
--output tablefor humans. - Errors: stable envelope
{ "error": { code, message, kind, details } }. - Exit codes: documented
IntEnum(0ok,1generic,2usage,3auth,4not-found,5connection,6config,7conflict,8unavailable). - Writes: dry-run by default;
--applyis the only gate and a dry-run opens no connection.