80 Commits

Author SHA1 Message Date
051e17ddf1 chore: bump to v1.0.0, drop native-tls for pure rustls
Removes openssl-sys transitive dep by disabling reqwest default
features, enabling static musl cross-compilation for Linux.
v1.0.0
2026-03-21 22:29:13 +00:00
7ebf9006a1 feat: wire 15 service subcommands into CLI, remove old user command
Adds Verb variants: auth, vcs, chat, search, storage, media, mon,
vault, people, docs, meet, drive, mail, cal, find. Each delegates
to the corresponding SDK cli.rs dispatch function.

Removes the legacy `user` command (replaced by `auth identity`).
Renames Get's -o to --kubectl-output to avoid conflict with the
new global -o/--output flag. Enables all SDK features in binary.
2026-03-21 22:20:15 +00:00
f867805280 feat: CLI modules for all 25+ service clients
One cli.rs per SDK module, gated behind #[cfg(feature = "cli")]:
- auth (identity + hydra): identity, session, recovery, schema,
  courier, health, client, jwk, issuer, token, SSO passthrough
- vcs (gitea): repo, issue, pr, branch, org, user, file, notification
- chat (matrix): room, message, state, profile, device, user, sync
- search (opensearch): doc, query, count, index, cluster, node,
  ingest pipeline, snapshot
- storage (s3): bucket, object
- media (livekit): room, participant, egress, token
- mon (prometheus, loki, grafana): queries, dashboards, datasources,
  folders, annotations, alerts, org
- vault (openbao): status, init, unseal, kv, policy, auth, secrets
- la suite (people, docs, meet, drive, mail, cal, find)

All dispatch functions take (cmd, &SunbeamClient, OutputFormat).
2026-03-21 22:18:58 +00:00
3d7a2d5d34 feat: OutputFormat enum + render/render_list/read_json_input helpers
Adds -o json|yaml|table output support to the SDK output module.
OutputFormat derives clap::ValueEnum behind the cli feature gate.
2026-03-21 22:17:10 +00:00
756fbc5e38 chore: update Cargo.lock 2026-03-21 20:38:53 +00:00
97976e0686 fix: include build module (was gitignored)
Bump: sunbeam-sdk v0.12.1
2026-03-21 20:37:54 +00:00
f06a167496 feat: BuildKit client + integration test suite (651 tests)
BuildKitClient CLI wrapper for buildctl.
Docker compose stack (9 services) for integration testing.
Comprehensive test suite: wiremock tests for Matrix/La Suite/S3/client,
integration tests for Kratos/Hydra/Gitea/OpenSearch/Prometheus/Loki/
Grafana/LiveKit.

Bump: sunbeam-sdk v0.12.0
2026-03-21 20:35:59 +00:00
b60e22edee feat: La Suite clients — 7 DRF services (75 endpoints)
PeopleClient, DocsClient, MeetClient, DriveClient, MessagesClient,
CalendarsClient, FindClient — all with DRFPage<T> pagination and
Bearer token auth.

Bump: sunbeam-sdk v0.11.0
2026-03-21 20:34:32 +00:00
915f0b254d feat: monitoring clients — Prometheus, Loki, Grafana (57 endpoints)
PrometheusClient (18 endpoints): query, metadata, targets, status.
LokiClient (11 endpoints): query, labels, series, push, index.
GrafanaClient (29 endpoints): dashboards, datasources, folders,
annotations, alerts, org.

Bump: sunbeam-sdk v0.10.0
2026-03-21 20:30:24 +00:00
21f9e18610 feat: LiveKitClient — real-time media API (15 endpoints + JWT)
Typed LiveKit Twirp API covering rooms, participants, egress,
and HMAC-SHA256 access token generation.

Bump: sunbeam-sdk v0.9.0
2026-03-21 20:29:44 +00:00
a33697c2fb feat: S3Client — object storage API (21 endpoints)
Typed S3-compatible API covering buckets, objects, multipart uploads,
tagging, versioning, lifecycle, CORS, ACL, and policies.

Bump: sunbeam-sdk v0.8.0
2026-03-21 20:28:49 +00:00
329c18bd1d feat: OpenSearchClient — search and analytics API (60 endpoints)
Typed OpenSearch API covering documents, search, indices, cluster,
nodes, cat, ingest pipelines, and snapshots.

Bump: sunbeam-sdk v0.7.0
2026-03-21 20:27:55 +00:00
2888d59537 feat: MatrixClient — chat and collaboration API (80 endpoints)
Typed Matrix client/server API covering auth, rooms, messages, state,
profiles, media, devices, E2EE, push, presence, and spaces.

Bump: sunbeam-sdk v0.6.0
2026-03-21 20:26:39 +00:00
890d7b80ac feat: GiteaClient — unified git forge API (50+ endpoints)
Typed Gitea REST API client with PAT auth covering repos, issues, PRs,
branches, orgs, users, file content, and notifications.

Bump: sunbeam-sdk v0.5.0
2026-03-21 20:24:48 +00:00
c597234cd9 feat: HydraClient — OAuth2/OIDC admin API (35 endpoints)
Typed Hydra admin API client covering OAuth2 clients, login/consent/logout
flows, JWK sets, trusted JWT issuers, sessions, and token introspection.

Bump: sunbeam-sdk v0.4.0
2026-03-21 20:22:39 +00:00
f0bc363755 feat: KratosClient — identity management (30 endpoints)
Typed Kratos admin API client covering identities, sessions,
recovery, schemas, courier messages, and health checks.

Bump: sunbeam-sdk v0.3.0
2026-03-21 20:20:08 +00:00
6823772055 feat: ServiceClient trait, HttpTransport, and SunbeamClient factory
Foundation layer for unified service client wrappers:
- AuthMethod enum (None, Bearer, Header, Token)
- ServiceClient trait with service_name(), base_url(), from_parts()
- HttpTransport with json(), json_opt(), send(), bytes() helpers
- SunbeamClient lazy factory with OnceLock-cached per-service clients
- Feature flags for all service modules (identity, gitea, matrix, etc.)

Bump: sunbeam-sdk v0.2.0
2026-03-21 20:15:11 +00:00
31fde1a8c6 fix: forge URL derivation for bare IP hosts, add Cargo registry config
forge_url() now checks active context domain first before falling back
to production_host. Bare IP addresses are skipped in the host heuristic.
Adds .cargo/config.toml for the sunbeam Gitea Cargo registry.
2026-03-21 15:17:47 +00:00
46d21330b1 docs: update README for Rust workspace layout 2026-03-21 14:51:45 +00:00
3ef3fc0255 feat: Python upstream — Sol bot registration TODO 2026-03-21 14:38:44 +00:00
e0961cce73 refactor: binary crate — thin main.rs + cli.rs dispatch
Slim binary that depends on sunbeam-sdk for all logic. Replaces 62
crate:: refs with sunbeam_sdk::. Tracing filter updated to include
sunbeam_sdk=info.
2026-03-21 14:38:33 +00:00
8e5d295902 refactor: SDK small command modules — services, cluster, manifests, gitea, update, auth 2026-03-21 14:38:25 +00:00
6c7e1cd064 refactor: SDK users, pm, and checks modules with submodule splits
Split users.rs (1157L) into mod.rs + provisioning.rs (mailbox,
projects user, welcome email). Split pm.rs (1664L) into mod.rs +
planka.rs (PlankaClient) + gitea_issues.rs (GiteaClient). Split
checks.rs (1214L) into mod.rs + probes.rs (11 check functions + S3).
2026-03-21 14:38:18 +00:00
bc65b9157d refactor: SDK images and secrets modules with submodule splits
Split images.rs (1809L) into mod.rs + builders.rs (per-service build
functions). Split secrets.rs (1727L) into mod.rs + seeding.rs (KV
get_or_create, seed_openbao) + db_engine.rs (PostgreSQL static roles).
Moves BuildTarget enum from cli.rs into images/mod.rs with conditional
clap::ValueEnum derive behind the "cli" feature.
2026-03-21 14:37:47 +00:00
8e51e0b3ae refactor: SDK kube, openbao, and tools modules
Move kube (client, apply, exec, secrets, kustomize_build) into kube/
submodule with tools.rs as a child. Move openbao BaoClient into
openbao/ submodule.
2026-03-21 14:35:43 +00:00
b92700d363 refactor: SDK core modules — error, config, output, constants
Move foundational modules into sunbeam-sdk. All crate-internal references
remain unchanged since these are sibling modules within the SDK crate.
2026-03-21 14:34:23 +00:00
2ffedb95cb refactor: workspace scaffolding — sunbeam-sdk + sunbeam binary crate
Convert the single binary crate into a Cargo workspace with two members:
sunbeam-sdk (library) and sunbeam (thin binary). Moves build.rs to the
SDK with adjusted .git/HEAD path for the nested layout.
2026-03-21 14:34:15 +00:00
b6daf608af chore: suppress dead_code warning on exit code constants 2026-03-20 21:33:00 +00:00
b92c6ad18c feat: Python upstream — onboard/offboard, mailbox, Projects, --no-cache
Python changes that were ported to Rust in preceding commits:
- User onboard/offboard with mailbox + Projects provisioning
- Welcome email with job title/department
- --no-cache build flag
- Date validation, apply confirmation, build targets
2026-03-20 21:32:23 +00:00
8d6e815a91 feat: --no-cache build flag and Sol build target
- Add --no-cache flag to sunbeam build (passes --no-cache to buildctl)
- Add Sol (virtual librarian) as a build target
- Wire no_cache through all build functions and dispatch
2026-03-20 21:31:42 +00:00
f75f61f238 feat: user provisioning — mailbox, Projects, welcome email
Onboarding now provisions app-level accounts:
- create_mailbox: Django ORM via kubectl exec into messages-backend
- setup_projects_user: knex.js via kubectl exec into projects pod
- Welcome email includes job title and department when provided

Offboarding cleans up:
- delete_mailbox: removes mailbox + Django user
- cleanup_projects_user: soft-deletes Planka user + memberships

All provisioning is best-effort (warns on failure, doesn't block).
2026-03-20 21:30:27 +00:00
c6aa1bd8ce feat: complete pm subcommands with board discovery and user resolution
Planka:
- Board discovery via GET /api/projects (no hardcoded IDs)
- String IDs (snowflake) throughout — TicketRef::Planka holds String
- Create auto-discovers first board/list, or matches --target by name
- Close finds "Done"/"Closed" list and moves card automatically
- Assign resolves users via search, supports "me" for self-assign
- Ticket IDs use p:/g: short prefixes

Gitea:
- Assign uses PATCH on issue (not POST /assignees which needs collaborator)
- Create requires --target org/repo

All pm subcommands tested against live Planka + Gitea instances.
2026-03-20 21:16:55 +00:00
ffc0fe917b feat: split auth into sso/git, Planka token exchange, board discovery
Auth:
- sunbeam auth login runs SSO (Hydra OIDC) then Git (Gitea PAT)
- SSO callback auto-redirects browser to Gitea token page
- sunbeam auth sso / sunbeam auth git for individual flows
- Gitea PAT verified against API before saving

Planka:
- Token exchange via /api/access-tokens/exchange-using-token endpoint
- Board discovery via GET /api/projects
- String IDs (snowflake) handled throughout

Config:
- kubectl-style contexts: --context flag > current-context > "local"
- Removed --env flag
- Per-domain auth token storage
2026-03-20 19:25:10 +00:00
ded0ab442e refactor: remove --env flag, use --context like kubectl
Context resolution: --context flag > current-context from config > "local".
No more production/local distinction in the CLI flags — the context
determines everything (domain, kube-context, ssh-host, infra-dir).

Remove Env enum entirely. Production detection is now "context has ssh-host".
2026-03-20 15:23:54 +00:00
88b02acdd1 feat: kubectl-style contexts with per-domain auth tokens
Config now supports named contexts (like kubectl), each bundling
domain, kube-context, ssh-host, infra-dir, and acme-email. Legacy
flat config auto-migrates to a "production" context on load.

- sunbeam config set --domain sunbeam.pt --host user@server
- sunbeam config use-context production
- sunbeam config get (shows all contexts)

Auth tokens stored per-domain (~/.local/share/sunbeam/auth/{domain}.json)
so local and production don't clobber each other. pm and auth commands
read domain from active context instead of K8s cluster discovery.
2026-03-20 15:17:57 +00:00
3a5e1c62ba fix: use predictable client_id via pre-seeded K8s secret
Pre-create oidc-sunbeam-cli secret with CLIENT_ID=sunbeam-cli before
hydra-maester reconciles. No cluster access needed at login time.
2026-03-20 15:08:59 +00:00
1029ff0747 fix: auth login UX — timeout, Ctrl+C, suppress K8s error, center HTML
- 5-minute timeout on callback wait (Ctrl+C now works)
- Skip K8s client_id lookup when no cluster configured (removes noisy ERROR)
- Center the success page HTML to match Sunbeam Studios branding
2026-03-20 14:31:59 +00:00
43b5a4eef9 fix: URL-encode scope parameter with %20 instead of + 2026-03-20 14:30:31 +00:00
7fab2a7f3c fix: auth login domain resolution with --domain flag
Domain resolves from: --domain flag > cached token > config
production_host > cluster discovery. Clear error when none available.
2026-03-20 14:29:08 +00:00
184ad85c60 fix: install rustls ring crypto provider at startup
Rustls 0.23 requires an explicit CryptoProvider. Enable the ring
feature and call install_default() before any TLS operations.
2026-03-20 14:15:16 +00:00
5bdb78933f feat: unified project management across Planka and Gitea
New src/pm.rs module with sunbeam pm subcommand:
- Planka client: cards, boards, lists, comments, assignments
  via OIDC token exchange for Planka JWT
- Gitea client: issues, comments, labels, milestones
  via OAuth2 Bearer token
- Unified Ticket type with p:/g: ID prefixes
- pm list: parallel fetch from both sources, merged display
- pm show/create/comment/close/assign across both systems
- Auth via crate::auth::get_token() (Hydra OAuth2)
2026-03-20 14:11:16 +00:00
d4421d3e29 feat: OAuth2 CLI authentication with PKCE and token caching
New src/auth.rs module:
- Authorization Code + PKCE flow via localhost redirect
- OIDC discovery from Hydra well-known endpoint
- Browser-based login (opens system browser automatically)
- Token caching at ~/.local/share/sunbeam/auth.json (0600 perms)
- Automatic refresh when access token expires (refresh valid 7 days)
- get_token() for use by other modules (pm, etc.)
- cmd_auth_login/logout/status subcommands
2026-03-20 14:10:37 +00:00
aad469e9c6 fix: stdin password, port-forward retry, seed advisory lock
- set-password reads from stdin when password arg omitted
- Port-forward proxy retries on pod restart instead of failing
- cmd_seed acquires PID-based advisory lockfile to prevent concurrent runs
2026-03-20 13:37:33 +00:00
dff4588e52 fix: employee ID pagination, add async tests
- next_employee_id now paginates through all identities (was limited to 200)
- Add #[tokio::test] tests: ensure_tunnel noop, BaoClient connection error,
  check_update_background returns quickly when forge URL empty
2026-03-20 13:37:25 +00:00
019c73e300 fix: S3 auth signature tested against AWS reference vector
Refactor s3_auth_headers into deterministic s3_auth_headers_at that
accepts a timestamp. Add test with AWS example credentials and fixed
date verifying canonical request, string-to-sign, and final signature.
2026-03-20 13:37:17 +00:00
e95ee4f377 fix: rewrite users.rs to fully async (was blocking tokio runtime)
Replace all blocking I/O with async equivalents:
- tokio::process::Command instead of std::process::Command
- tokio::time::sleep instead of std::thread::sleep
- reqwest::Client (async) instead of reqwest::blocking::Client
- All helper functions (api, find_identity, generate_recovery, etc.) now async
- PortForward::Drop uses start_kill() (sync SIGKILL) for cleanup
- send_welcome_email wrapped in spawn_blocking for lettre sync transport
2026-03-20 13:31:45 +00:00
24e98b4e7d fix: CNPG readiness, DKIM SPKI format, kv_patch, container name
- Check CNPG Cluster CRD status.phase instead of pod Running phase
- DKIM public key: use SPKI format (BEGIN PUBLIC KEY) matching Python
- Use kv_patch instead of kv_put for dirty paths (preserves external fields)
- Vault KV only written when password is newly generated
- Gitea exec passes container name Some("gitea")
- Fix openbao comment (400 not 409)
2026-03-20 13:29:59 +00:00
6ec0666aa1 fix: SSH tunnel leak, cmd_bao injection, discovery cache, DNS async
- Store SSH tunnel child in static Mutex (was dropped immediately)
- cmd_bao: use env(1) for VAULT_TOKEN instead of sh -c (no shell injection)
- Cache API discovery across kube_apply documents (was per-doc roundtrip)
- Replace blocking ToSocketAddrs with tokio::net::lookup_host
- Remove double YAML->JSON->string->JSON serialization in kube_apply
- ResultExt::ctx now preserves all SunbeamError variants
2026-03-20 13:29:51 +00:00
bcfb443757 refactor: deduplicate constants, fix secret key mismatch, add VSS pruning
- New src/constants.rs: single source for MANAGED_NS (includes monitoring)
  and GITEA_ADMIN_USER, imported by all modules that previously had copies
- Fix checks.rs reading wrong key names from gitea-admin-credentials secret
- Add VaultStaticSecret pruning in pre_apply_cleanup (H1)
- Fix cert_manager_present check (was always true after canonicalize)
- Add warnings for silent failures in pre_apply_cleanup
- Fix os_api dead variable assignment
- Set TLS private key permissions to 0600
- Redact Gitea admin password in print_urls
2026-03-20 13:29:35 +00:00
503e407243 feat: implement OpenSearch ML setup and model_id injection
ensure_opensearch_ml: cluster settings, model registration/deployment
(all-mpnet-base-v2), ingest + search pipelines for hybrid BM25+neural.

inject_opensearch_model_id: reads model_id from ingest pipeline,
writes to matrix/opensearch-ml-config ConfigMap.

os_api helper: kube exec curl inside opensearch pod.
2026-03-20 13:16:00 +00:00