Collects infrastructure inventory (host info, disks, NICs, mounts, users/groups, daemons, packages) from hosts over SSH and stores it in a PostgreSQL database.
- Python 3.10+
- PostgreSQL (with
psycopgdriver support) - SSH access to target hosts (key-based or password auth)
pip install -r requirements.txt # click, sqlalchemy, alembic, paramiko, pyyaml, psycopg
cp example.config.yaml config.yamlconfig.yaml (or the file pointed to by TPA_CONFIG):
database:
url: "postgresql+psycopg://tpa_user:changeme@localhost:5432/tpa"
ssh:
port: 22
timeout: 30
max_workers: 32
credential: default # name of the credentials entry to use
strict_host_key_checking: new # true | new | false (see below)
# known_hosts_path: ~/.ssh/known_hosts
# retries: 1 # extra connection attempts after the first
credentials:
default:
type: pkey # or "userpass"
username: svc_account
key_path: /home/chad/.ssh/id_rsa
passphrase: null # or "userpass": password: ...
# vault:
# type: userpass
# username: vault_agent
# password: ...ssh.max_workerscontrols the concurrency of parallel host collection.ssh.credentialselects whichcredentials.<name>entry is used for all hosts (defaults todefault).ssh.strict_host_key_checkingcontrols SSH host key verification:new(default): unknown host keys are accepted once and recorded inknown_hosts_path, like OpenSSHStrictHostKeyChecking=accept-new.true: unknown or changed host keys are rejected with an actionable error (including the expected fingerprint); bootstrap withssh-keyscan -p <port> <host> >> ~/.ssh/known_hosts.false: any host key is accepted without verification (insecure — do not use in production).
ssh.retriesis the number of additional connection attempts after a transient failure (not used for authentication or host key errors).
sync foreman pulls errata counts from Satellite and stores them on each host.
The satellite block in config.yaml configures the connection:
satellite:
url: "https://foreman.example.com"
username: admin
password: adminadmin
# token: <api-token> # alternative to username/password
verify_ssl: false # only if the Satellite cert chain is untrusted
# timeout: 30
# per_page: 100
# max_workers: 16verify_ssl: false disables TLS certificate verification for the Satellite
API — set it only when the certificate chain cannot be trusted, and prefer
wiring the Satellite CA into the system trust store instead.
python tpa.py migrate
# or directly: alembic upgrade headpython tpa.py <command>
Reads a CSV of hosts, SSHes into each, collects host info, and upserts into the DB:
python tpa.py synchosts hosts.csvCSV layout - host is required; adjacent property columns are mapped onto
dedicated host attributes, and any other column is stored in the extra JSONB:
host,environment,service,function,role,sequence,owner,description,patching_group,has_dr,dr_method,custom_field
web01.example.com,prod,checkout,web,app,01,team-a,"Frontend node",week1,yes,backup-site,anything
db01.example.com,prod,database,db,primary,02,team-b,,week2,no,,Host property columns:
| Column | Type | Notes |
|---|---|---|
environment |
varchar | e.g. prod, dev, test |
service |
varchar | |
function |
varchar | |
role |
varchar | |
sequence |
varchar | |
owner |
varchar | |
description |
text | |
patching_group |
varchar | |
has_dr |
boolean | accepts true/1/yes/y/on, empty = unset |
dr_method |
varchar |
Any other column in the CSV (e.g. custom_field) is stored in hosts.extra.
Runs over every host currently in the database:
python tpa.py syncdisks # disks
python tpa.py syncnet # NICs / IP addresses
python tpa.py syncmounts # mounts
python tpa.py syncusers # users and groups (with sudo flags)
python tpa.py syncdaemons # systemd daemons
python tpa.py syncpkg # installed packages
python tpa.py sync foreman # errata counts from Satellite
python tpa.py syncall # all of the aboveResources no longer present on a host are marked is_stale rather than deleted.
Export any inventory table as CSV to stdout and/or a file:
python tpa.py get hosts --stdout
python tpa.py get hosts --csv hosts-report.csv
python tpa.py get disks --csv disks.csv
python tpa.py get net --csv net.csv
python tpa.py get mounts --stdout
python tpa.py get groups --csv groups.csv
python tpa.py get users --csv users.csv
python tpa.py get daemons --csv daemons.csv
python tpa.py get pkg --csv packages.csvAvailable reports: hosts, disks, net, mounts, groups, users,
daemons, pkg. At least one of --csv or --stdout is required.
cp example.config.yaml config.yamland fill in database URL + SSH credentials.python tpa.py migratepython tpa.py synchosts hosts.csvpython tpa.py syncallpython tpa.py get hosts --stdout
tpa.py- CLI entry pointlib/commands/- click commands (synchosts, sync*, get, migrate)lib/collectors/- per-resource SSH collectorslib/models.py- SQLAlchemy modelslib/sync_runner.py- shared parallel sync logiclib/ssh.py- SSH connection handlingalembic/- schema migrations