Initial implementation of inventree
A small IT asset inventory system built around a nested folder tree, matching the project brief: Go + html/template + Bootstrap 5 + vanilla JS, SQLite storage (WAL, FKs, migrations), embedded templates/static assets, single compiled binary. - AJAX-driven inventory tree: lazy-loaded folder expansion with per-user persisted expand state, drag-and-drop move for folders/assets, safe delete-with-relocate-or-cascade confirmation, search with breadcrumbs. - Assets: CRUD, duplicate, move, auto-generated IT-000001-style IDs, CSV import (with optional folder auto-create) and export. - Admin-defined item types with custom fields (text/long_text/number/date/ boolean/dropdown/url/ip_address). - Configurable statuses, session-based auth (bcrypt, secure cookies), admin/user roles, user management. - CLI: serve, version, database migrate, database backup; /healthz; graceful shutdown; Dockerfile/docker-compose/systemd unit; Go test suite.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# inventree
|
||||
|
||||
A small, self-contained IT asset inventory system. The heart of inventree is a
|
||||
nested folder tree — like a file manager — for organizing physical and
|
||||
virtual IT assets (servers, switches, laptops, printers, etc.).
|
||||
|
||||
- Single compiled Go binary, embedded HTML templates and static assets
|
||||
- SQLite storage (WAL mode, foreign keys, migrations)
|
||||
- Bootstrap 5 UI, minimal vanilla JavaScript (no Node/React/build step)
|
||||
- Session-based auth with two roles: Admin and User
|
||||
- Custom, admin-defined asset types with custom fields
|
||||
- CSV import/export, full-text-ish search with breadcrumbs
|
||||
|
||||
## Quick start
|
||||
|
||||
```sh
|
||||
go build -o inventree ./cmd/inventree
|
||||
./inventree serve
|
||||
```
|
||||
|
||||
Then open http://localhost:8080 and log in with:
|
||||
|
||||
```
|
||||
Username: admin
|
||||
Password: admin
|
||||
```
|
||||
|
||||
(This default account is created intentionally on first run. Change or
|
||||
disable it via the Users admin page once you're up and running.)
|
||||
|
||||
The database file is created automatically at `data/inventree.db` on first
|
||||
run, with migrations applied and seed data (default statuses, item types,
|
||||
and the admin account) inserted.
|
||||
|
||||
## CLI
|
||||
|
||||
```sh
|
||||
inventree # same as `inventree serve`
|
||||
inventree serve # start the web server
|
||||
inventree version # print the version
|
||||
inventree database migrate # apply pending migrations and exit
|
||||
inventree database backup [path] # write a consistent VACUUM INTO snapshot
|
||||
```
|
||||
|
||||
`serve` flags:
|
||||
|
||||
| Flag | Default | Description |
|
||||
|---------------------|------------------------|--------------------------------------------|
|
||||
| `-addr` | `:8080` | Listen address |
|
||||
| `-db` | `data/inventree.db` | Path to the SQLite database file |
|
||||
| `-secure-cookies` | `false` | Mark the session cookie `Secure` (enable when serving over HTTPS) |
|
||||
|
||||
`/healthz` is available for load balancer / container health checks.
|
||||
|
||||
## The inventory tree
|
||||
|
||||
The Inventory page is the default page after login and the center of the
|
||||
application: a folder/asset tree on the left, and a detail panel on the
|
||||
right that shows whatever is selected (a folder's contents, or a single
|
||||
asset).
|
||||
|
||||
- **Folders** can nest arbitrarily deep, and contain both subfolders and
|
||||
assets.
|
||||
- **Expand/collapse** state is remembered per user (persisted server-side),
|
||||
and folder contents are fetched lazily via small AJAX requests — the page
|
||||
never fully reloads when you browse the tree.
|
||||
- **Drag and drop** folders and assets onto another folder (or onto
|
||||
"Inventory" itself) to move them. Admin only.
|
||||
- **Right-click-style actions**: each folder has a "…" action menu (New
|
||||
Subfolder, Add Asset, Rename, Delete).
|
||||
- **Deleting a folder** that still contains subfolders or assets requires
|
||||
confirmation, and offers a safe "move contents elsewhere" option instead
|
||||
of an accidental cascade. A "permanently delete everything inside" option
|
||||
is also available for when that's genuinely what you want.
|
||||
- **Search** (top of the tree pane) looks across asset ID, name, folder
|
||||
name, item type, assigned user, notes, and custom field values, and shows
|
||||
each result's full folder breadcrumb.
|
||||
|
||||
## Item types and custom fields
|
||||
|
||||
Admins can define arbitrary asset types (Laptop, Switch, Firewall, …) under
|
||||
**Item Types**, each with its own set of custom fields (text, long text,
|
||||
number, date, boolean, dropdown, URL, IP address), marked required or not,
|
||||
with a default value and display order. A representative starter set of
|
||||
types and fields is seeded on first run — feel free to edit or delete it.
|
||||
|
||||
## CSV import / export
|
||||
|
||||
- **Export**: from the Inventory toolbar, or `/export/assets.csv` (optionally
|
||||
scoped to a folder, with `?recursive=1` to include subfolders). Includes
|
||||
one `cf_<field_key>` column per distinct custom field in use.
|
||||
- **Import**: CSV with columns `Asset ID` (optional — auto-generated if
|
||||
blank), `Name`, `Item Type`, `Folder` (a `/`-separated path, e.g.
|
||||
`Main Office/Network`), `Status`, `Assigned User`, `Notes`, plus
|
||||
`cf_<field_key>` columns for custom fields. Existing assets are matched
|
||||
and updated by Asset ID; everything else is created. Missing folders in
|
||||
the path can optionally be created automatically.
|
||||
|
||||
A full backup/restore of everything (folders, assets, types, custom fields,
|
||||
statuses) is just `inventree database backup` — it's a consistent snapshot
|
||||
of the whole SQLite database.
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
cmd/inventree/ CLI entrypoint (serve, version, database migrate/backup)
|
||||
internal/
|
||||
auth/ session management, secure cookies
|
||||
database/ SQLite connection, pragmas, migrations
|
||||
migrations/ embedded .sql migration files
|
||||
models/ shared domain types
|
||||
folders/ nested folder tree
|
||||
assets/ asset CRUD, search, CSV import/export
|
||||
itemtypes/ admin-defined types + custom field definitions
|
||||
users/ accounts
|
||||
statuses/ configurable asset statuses
|
||||
settings/ key/value app settings
|
||||
web/ HTTP router, handlers, template rendering
|
||||
web/
|
||||
templates/ Go html/template pages and partials (embedded)
|
||||
static/ Bootstrap 5, Bootstrap Icons, app.css, app.js (embedded)
|
||||
deploy/ systemd unit example
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
go build ./...
|
||||
go vet ./...
|
||||
go test ./...
|
||||
```
|
||||
|
||||
The SQLite driver is [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite),
|
||||
a pure-Go implementation, so `CGO_ENABLED=0` builds work out of the box and
|
||||
the compiled binary has no C library dependencies.
|
||||
|
||||
## Docker
|
||||
|
||||
```sh
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
This builds the image, starts inventree on port 8080, and persists the
|
||||
database in a named volume (`inventree-data`, mounted at `/app/data`).
|
||||
|
||||
Or directly:
|
||||
|
||||
```sh
|
||||
docker build -t inventree .
|
||||
docker run -p 8080:8080 -v inventree-data:/app/data inventree
|
||||
```
|
||||
|
||||
## systemd
|
||||
|
||||
See `deploy/inventree.service` for an example unit. Adjust the paths, then:
|
||||
|
||||
```sh
|
||||
sudo useradd --system --home /opt/inventree --shell /usr/sbin/nologin inventree
|
||||
sudo mkdir -p /opt/inventree/data
|
||||
sudo cp inventree /opt/inventree/inventree
|
||||
sudo chown -R inventree:inventree /opt/inventree
|
||||
sudo cp deploy/inventree.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now inventree
|
||||
```
|
||||
|
||||
## Scope
|
||||
|
||||
inventree is intentionally a focused MVP: folders, assets, custom types,
|
||||
statuses, users, search, and CSV import/export. It does not include
|
||||
ticketing, purchasing, monitoring, RMM, MDM, or accounting features — if you
|
||||
need those, look elsewhere and integrate via CSV.
|
||||
Reference in New Issue
Block a user