docs: surface the Directory doc — register in-app, link from UI and site
docs/directory.md existed but was orphaned: not in the /docs registry,
not linked anywhere. Now:
- registered as /docs/directory ("Directory & Inventory")
- help icon on the Directory page header links to it (same pattern as
users/groups/profile pages)
- linked from the docs site index feature list
- extended with the shared slug conventions (site_<name>, host_<hostname>),
the automatic registration story (theta-env stack seeding, ldap-client
Linux host enrollment), and the admin + read-only API surface (the
read-only graph routes live at /api/discovery, not /api/directory).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -57,3 +57,41 @@ Resources carry a flexible `metadata` JSON object that can store essential conte
|
|||||||
## Navigating the UI
|
## Navigating the UI
|
||||||
|
|
||||||
The Directory Management interface provides a **Tree View** toggle that visually nests your resources, making it easy to comprehend your network topography at a glance. You can also filter, search, and sort your entire infrastructure inventory. From the tree view, you can click the green `+` icon next to any resource to instantly add a child resource beneath it.
|
The Directory Management interface provides a **Tree View** toggle that visually nests your resources, making it easy to comprehend your network topography at a glance. You can also filter, search, and sort your entire infrastructure inventory. From the tree view, you can click the green `+` icon next to any resource to instantly add a child resource beneath it.
|
||||||
|
|
||||||
|
## Slug conventions
|
||||||
|
|
||||||
|
Slugs are the stable identifiers automation keys off, so the tooling around the SSO Manager follows a shared convention:
|
||||||
|
|
||||||
|
- **Sites**: `site_<name>` — e.g. `site_local`, `site_us-east`
|
||||||
|
- **Hosts**: `host_<hostname>` — e.g. `host_pve1`, `host_web01`
|
||||||
|
- **Services/apps**: a plain slug or `app_<name>` — e.g. `sso-manager`, `app_emby`
|
||||||
|
|
||||||
|
The auto-created LDAP groups derive from the slug (`<slug>_access` / `<slug>_admin`), so keep slugs stable once access groups are in use.
|
||||||
|
|
||||||
|
## Automatic registration
|
||||||
|
|
||||||
|
You don't have to build the graph by hand — the theta42 tooling registers itself:
|
||||||
|
|
||||||
|
### The stack itself (theta-env)
|
||||||
|
|
||||||
|
[theta-env](https://github.com/theta42/theta-env)'s `./setup.sh` seeds the directory on every run with the stack it deploys:
|
||||||
|
|
||||||
|
- a **site** (name from `CFG_SITE_NAME` in `setup.env`, default `local` → slug `site_local`) marked as the current site
|
||||||
|
- the **host** the stack runs on (`host_<hostname>`), with IP, MAC address, OS, and kernel collected from the machine
|
||||||
|
- the **services** it composes — SSO Manager, Proxy (management UI), OpenLDAP Directory (the LDAPS endpoint Linux hosts and LDAP-native apps bind to), and OpenResty Edge (the 80/443 data plane) — each with its address, internal port, and git repo
|
||||||
|
- the proxy's auto-registered **OAuth client**, linked under its service
|
||||||
|
|
||||||
|
The seed is idempotent and non-destructive: a resource whose slug already exists is considered operator-owned — the seed only fills in metadata fields you haven't set, and never overwrites your values.
|
||||||
|
|
||||||
|
### Linux hosts (ldap-client)
|
||||||
|
|
||||||
|
The `ldap-client` join script enrolls a Debian/Ubuntu machine for LDAP login (SSSD/PAM), LDAP-backed `sudo`, and SSH keys from the directory — and, when given an SSO API token, registers the machine as a `host_<hostname>` resource with its IP, MAC, OS, and kernel, parented to the site named by its configured location.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
All of the above uses the same admin API the UI does (group `app_sso_directory_admin` or `app_sso_admin`):
|
||||||
|
|
||||||
|
- `GET/POST /api/directory-admin/resources`, `PUT/DELETE /api/directory-admin/resources/:id`
|
||||||
|
- `GET/POST/DELETE /api/directory-admin/edges` — parent/child links (`hosts`, `oauth` relations)
|
||||||
|
- `GET/POST/DELETE /api/directory-admin/groups` — resource ↔ LDAP group links
|
||||||
|
- Read-only graph views (any authenticated user): `GET /api/discovery/resources`, `/api/discovery/resources/:slug`, `/api/discovery/graph`, `/api/discovery/me`
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ backend, that's the niche.
|
|||||||
- **All-in-one Docker image** — app + OpenLDAP + Redis in one container, or
|
- **All-in-one Docker image** — app + OpenLDAP + Redis in one container, or
|
||||||
run the pieces separately via `app_*` env config.
|
run the pieces separately via `app_*` env config.
|
||||||
- **Geo-Location Scaling** — built-in support for N-Way Multi-Master OpenLDAP [replication](replication.html) across physical sites.
|
- **Geo-Location Scaling** — built-in support for N-Way Multi-Master OpenLDAP [replication](replication.html) across physical sites.
|
||||||
|
- **[Directory & Inventory](directory.html)** — map sites, hosts, and services as a graph with rich metadata (IP/MAC, OS/kernel, ports, git repos), auto-provisioned access groups, and automatic registration from theta-env and ldap-client.
|
||||||
|
|
||||||
## Get it
|
## Get it
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const DOCS = {
|
|||||||
accounts: {title: 'Accounts, Groups & Managers', file: path.join(__dirname, '../../docs/concepts-accounts.md')},
|
accounts: {title: 'Accounts, Groups & Managers', file: path.join(__dirname, '../../docs/concepts-accounts.md')},
|
||||||
'oauth-apps': {title: 'Connecting Apps (SSO)', file: path.join(__dirname, '../../docs/concepts-oauth-apps.md')},
|
'oauth-apps': {title: 'Connecting Apps (SSO)', file: path.join(__dirname, '../../docs/concepts-oauth-apps.md')},
|
||||||
'api-tokens': {title: 'API Tokens', file: path.join(__dirname, '../../docs/concepts-api-tokens.md')},
|
'api-tokens': {title: 'API Tokens', file: path.join(__dirname, '../../docs/concepts-api-tokens.md')},
|
||||||
|
directory: {title: 'Directory & Inventory', file: path.join(__dirname, '../../docs/directory.md')},
|
||||||
|
|
||||||
overview: {title: 'Overview', file: path.join(__dirname, '../../README.md')},
|
overview: {title: 'Overview', file: path.join(__dirname, '../../README.md')},
|
||||||
changelog: {title: 'Changelog', file: path.join(__dirname, '../../CHANGELOG.md')},
|
changelog: {title: 'Changelog', file: path.join(__dirname, '../../CHANGELOG.md')},
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<div class="card-header actionMessage" style="display:none"></div>
|
<div class="card-header actionMessage" style="display:none"></div>
|
||||||
<div class="p-3 pb-0 text-muted small border-bottom">
|
<div class="p-3 pb-0 text-muted small border-bottom">
|
||||||
<i class="fa-solid fa-circle-info"></i> Manage infrastructure, services, and their relationships.
|
<i class="fa-solid fa-circle-info"></i> Manage infrastructure, services, and their relationships.
|
||||||
|
<a href="/docs/directory" class="text-reset float-end" title="Help"><i class="fa-solid fa-circle-question"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="card-body table table-striped mb-0">
|
<table class="card-body table table-striped mb-0">
|
||||||
|
|||||||
Reference in New Issue
Block a user