Commit Graph

228 Commits

Author SHA1 Message Date
Tower Bot
816328b49d tower 0.61.6 — hide platform cluster from tenant-scoped server lists
handleListServers's existing tenant filter would still admit a
platform cluster (type='platform') if it had been mis-labeled with
a tenant or if a tenant happened to host an instance there. Belt-
and-braces: explicit reject of any cluster with type='platform'
when the request is tenant-scoped (non-super-admin). The platform
control-plane runs Tower itself + platform-tenant template builds
— it is not a deployment target for customer tenants and surfacing
it in their Server picker breaks the bring-your-own-cluster model.

Caught while smoke-testing MigrateDrawer: a fresh tenant's Server
dropdown defaulted to 'Platform server', risking a customer
deploying their tenant data onto the operator's shared infra by
accident.
2026-04-30 11:54:32 +03:00
Tower Bot
53d8a21a19 tower 0.61.5 / tower-ui 0.61.9 — domain on Argo App, no more hardcode
The instance row's '<code>.tenants.odoosky.org' was being computed
client-side from the code alone, so a tenant whose domain is
'4th.online' still saw 'odoo16.tenants.odoosky.org' in the list +
the Open button — wrong zone, no cert, scary Firefox warning.

Backend: Argo App now carries an 'odoosky.io/domain' annotation
written at create time from req.Domain (the values.yaml domain),
read back in argoApplicationSummary.Domain. Delete handler reads
the same annotation so DNS cleanup hits the right Cloudflare zone
instead of the platform default.

Frontend: Instance.domain field, used by InstancesView, Vitals,
ActionBar, with a fallback to the legacy pattern for any pre-Phase-F
Argo App that hasn't been backfilled yet.

Backfill for live odoo16: kubectl annotate done out-of-band.
2026-04-30 11:47:07 +03:00
Tower Bot
dcef586b21 tower-ui 0.61.8 — Deploy/Migrate drawers read tenant wildcard
DeployInstanceDrawer + MigrateDrawer were hardcoding
'<code>.tenants.odoosky.org' as the auto-suggested instance domain,
even when the operator's tenant has its own domain set in Settings.
A tenant whose wildcardHost is '*.tenants.4th.online' would still see
the wizard pre-fill 'odoo16.tenants.odoosky.org' in the Domain field —
the suggestion landed in the wrong zone, instance create would fail
DNS write.

Both drawers now fetch /api/tenants/<id>/settings on mount and use
'tenants.<domain>' (with leading '*.' stripped from wildcardHost) as
the suffix, falling back to odoosky.org only if the call errors or
the field is empty.
2026-04-30 11:32:00 +03:00
Tower Bot
31e05e96c1 tower 0.61.4 — stamp owner tenant on cluster Secret at connect time
UpsertCluster was not setting the odoosky.io/tenant-id label on the
ArgoCD cluster Secret. Result: handleListServers tenant filter
attributed every freshly-connected cluster to no-tenant, making the
just-connected box invisible to the operator who registered it.

Threads ownerTenantID from the connect token through to the body of
the POST /api/v1/clusters call. Backfill of any pre-fix cluster
Secret is a one-line kubectl label.
2026-04-30 11:25:20 +03:00
Tower Bot
61669ff704 tower 0.61.3 — fix CF token Vault key mismatch
cloudflare_resolver.go reads data['token'] but the writer (and the
test endpoint) stores under data['api_token']. Result: every fresh
tenant's CF resolver returned no token even when one was saved,
killing DNS records view AND any instance lifecycle DNS write.

Caught while smoke-testing the multi-tenant signup flow.
2026-04-30 11:12:28 +03:00
Tower Bot
28f15c92f3 tower 0.61.2 / tower-ui 0.61.7 — fixes from end-to-end smoke
3 bugs caught while smoke-testing the multi-tenant signup → first
deploy flow:

1. /api/me returned capabilities: null when scope.role was nil
   (a tenant member viewing the platform tenant context). Frontend's
   useAuth.can() does for-of on the array → TypeError. Fix: backend
   returns []string{} not nil; frontend defends against null.

2. WelcomeView slug input pattern '[a-z][a-z0-9-]{2,39}' is rejected
   by Firefox's HTML5 form validation under the v-flag (treats trailing
   '-' as a class-range start). Move hyphen to start of the class.

3. Domain & DNS Save button is genuinely separate from the Cloudflare
   token Save (by design — token rotates independently). Documenting
   here so the next person doesn't think they saved when they didn't.
2026-04-30 11:03:12 +03:00
Tower Bot
9d9138231a tower 0.61.1 — Phase F (B): tenant-scoped S3 resolver
Refactor s3Resolver from a single-global-creds reader into a
tenant-scoped factory. Each tenant brings their own S3 endpoint,
region, three named buckets (backups + templates + audit), and
access keys (in Vault at v3/tenants/<id>/s3-credentials).

Touches:
  s3.go         — s3Resolver becomes factory; tenantS3 wraps
                  one minio.Client + bucket per tenant
  audit.go      — events grouped by tenantID per flush, written
                  to the tenant's audit bucket
  backups.go    — fleet view fans out one S3 LIST per tenant;
                  per-instance handlers resolve via Argo App
  export/import/migrate — tenant resolved from Argo App label
                  or scope.TenantID
  templates_*   — per-template tenant lookup via templateTenantID
                  (platform tenant for OwnerPlatform manifests)
  vitals.go     — last-backup probe pulls tenantID before list

Adds AllTenants() to PlatformStore so the templates orphan sweep
can iterate every tenant configured with a templates bucket.

Build: tower:0.61.1 — pushed to registry.odoosky.cloud
2026-04-30 10:37:24 +03:00
ops
3370097dcc tower 0.61.0 — Stage 2: per-tenant Gitea org for instance overlays (instance-<code> in tenant-<slug>) 2026-04-30 00:16:34 +03:00
ops
d81c313543 tower 0.60.12 — Stage 1: per-tenant Gitea org provisioned on tenant create/delete 2026-04-29 23:59:42 +03:00
ops
efce4b2e1d tower 0.60.11 / tower-ui 0.61.6 — wildcard cert badge on Server Detail 2026-04-29 23:39:42 +03:00
ops
77331e5e70 tower 0.60.10 — pass cluster.name helm param (per-cluster differentiator SAN) 2026-04-29 23:27:39 +03:00
ops
a912284226 tower 0.60.9 — apply cloudflare-api-token Secret to odoosky-system 2026-04-29 23:06:56 +03:00
ops
76d1ab036d tower 0.60.8 — Argo App: SkipDryRunOnMissingResource + retry limit 10 (CRD-ordering) 2026-04-29 22:32:04 +03:00
ops
7b2fadd132 tower-ui 0.61.5 — Connect drawer: no auto-close on success, manual Done button 2026-04-29 22:25:37 +03:00
ops
78bc427201 tower 0.60.7 — set source.path=. on per-cluster platform Application 2026-04-29 22:20:46 +03:00
ops
36c4d32d51 tower 0.60.6 — rewrite kubeconfig server URL before applying secrets (URL-token Connect) 2026-04-29 22:15:32 +03:00
ops
333850d994 tower 0.60.5 — bootstrap.sh: poll for node before kubectl wait (fixes kubectl --all race on fresh k3s) 2026-04-29 22:09:47 +03:00
ops
9aa2466d8d tower 0.60.4 / tower-ui 0.61.4 — disconnect resilient to dead customer cluster 2026-04-29 21:53:00 +03:00
ops
b498e79dad tower-ui 0.61.3 — consolidate S3 settings UX (5 buttons → 2) 2026-04-29 21:37:30 +03:00
Claude
5dfdd7faa0 tower 0.60.3 — register POST /api/tenants/{id}/settings/s3-buckets/provision
Backend rebuild for the route I added in 0.60.2 + ui:0.61.2 cycle —
forgot to rebuild Go binary alongside the chart bump. 0.60.2 binary
didn't carry the handler, hence the 404 on Provision now click.
2026-04-29 21:26:29 +03:00
Claude
d8404ef309 tower-ui 0.61.2 — Provision now button for S3 buckets
POST /api/tenants/{id}/settings/s3-buckets/provision uses stored
creds to HeadBucket+MakeBucket the three derived buckets idempotently,
then persists their names to YAML. Surfaces in Settings → Backups
panel as 'Provision now' button next to the bucket list. Lets the
operator create buckets without rotating keys.
2026-04-29 21:21:49 +03:00
Claude
12250b43dd tower 0.60.2 — Test endpoint derives bucket names from slug
handleTestS3Credentials no longer requires bucket names in YAML —
testTenantS3Buckets derives from slug, same as Save's auto-create.
Test stored creds now works whether the buckets have been created
yet or not. Per-bucket result still surfaces 404 vs 403 vs other.
2026-04-29 21:15:48 +03:00
Claude
3b9d942725 tower 0.60.1 / tower-ui 0.61.1 — auto-create + auto-name S3 buckets
Tenant pastes endpoint + region + access keys. Tower auto-derives
3 bucket names from slug (<slug>-backups, -templates, -audit) and
HeadBucket+MakeBucket each at credential-save time. UI removes the
3 bucket-name inputs entirely; shows what will be created instead.

Removes the 'go to MEGA dashboard, click new bucket × 3' toil.
One credential save = three buckets ready.
2026-04-29 21:09:03 +03:00
Claude
b89c084ebd tower 0.60.0 / tower-ui 0.61.0 — Phase F.1: three buckets per tenant
Data model: PlatformTenant.S3 = { Endpoint, Region, Buckets: { Backups, Templates, Audit } }
Vault: legacy v3/data/s3{,-templates,-audit} paths wiped (decision in
docs/decisions/0001 path is bring-your-own only; per-tenant only).
UI: 3 bucket fields (Backups / Templates / Audit), single endpoint +
region + credential pair. Test does HeadBucket on each configured
bucket and reports per-bucket pass/fail.

Note: writers (audit/templates/backups handlers) still read from old
paths. Phase F.2 (next) sweeps the ~30 call sites onto a tenant-scoped
s3Factory. Tower compiles + serves API; backups+audit+templates writes
are non-functional until F.2 lands. v3 has no customers, so the
breakage window is tolerable per memory feedback_v3_disposable_no_customers.
2026-04-29 20:58:26 +03:00
Claude
4922dd6e9c fix: restore backend image.repository (clobbered by chart bump again) 2026-04-29 20:37:11 +03:00
Claude
742adfff92 tower 0.59.2 — bring-your-own only: drop platform-Vault rung from CF resolver
Per docs/decisions/0001-platform-fallback-deferred.md, instance DNS
automation no longer silently falls back to v3/platform/cloudflare-token.
Tenants without a configured CF token get a clear error at instance
create instead of pretending to work via shared infrastructure.
The platform Vault entry stays seeded for future revival.
2026-04-29 20:36:46 +03:00
Claude
86b545cf40 fix: restore image.repository keys clobbered by chart bump 2026-04-29 20:02:59 +03:00
Claude
f230056e51 tower 0.59.1 / tower-ui 0.60.0 — partial settings updates + per-card Save
Backend: UpdateTenantSettingsReq → pointer fields. Each card saves
only its own keys without clobbering the other card.

Frontend:
- 'Save Domain & DNS' button inside the Domain & DNS card
- 'Save Backups target' button inside the S3 card
- Wildcard host hidden behind 'Advanced — customize wildcard host'
  disclosure. Default is shown as read-only display under Domain so
  the operator sees what URLs their instances will land at.
- Removed the global Save settings button (each card now self-saves)
2026-04-29 19:58:21 +03:00
Claude
7b62631489 tower-ui 0.59.1 — wildcard host: value-based custom detection
Replace event-based 'touched' flag with computed isCustomWildcard.
Empty wildcard or wildcard==derived → 'auto-derived', auto-fills
on domain change. Different from derived → 'custom', sticks.
Fixes the empty-after-delete trap that kept touched=true forever.
2026-04-29 19:44:38 +03:00
Claude
082feb1e58 tower 0.59.0 — Live DNS records panel + wildcard auto-derive
- new GET /api/tenants/{id}/dns/records endpoint lists A+CNAME records
  in the tenant's CF zone matching the wildcard pattern (read-only)
- TenantSettingsTab.vue: 'Live DNS records' panel with refresh button
- wildcard host auto-derives from domain (visible value, not placeholder)
- placeholder text now generic *.tenants.example.com
2026-04-29 19:33:11 +03:00
Claude
6f926cb3df tower-ui 0.58.2 — wildcard host auto-derives from domain
Placeholder text (*.tenants.acme-erp.com) was prescriptive and
indistinguishable from the saved value. Now wildcard auto-derives
from the domain field as a real value (visible, savable, editable).
'reset to default' button surfaces when user customises.
2026-04-29 18:45:16 +03:00
Claude
ea54300706 tower-ui 0.58.1 — sidebar 'Tenant' link for tenant owners
Tenant owners had no nav link to their own tenant settings page.
Adds a 'Tenant' workspace link visible to authenticated members
of any tenant. Super-admins still use /admin/tenants list (which
shows all tenants and lets them switch).
2026-04-29 18:19:48 +03:00
Claude
cfdffc9804 tower 0.58.2 — sync platform-store reload after commits
Fixes signup race: verify→/me 401 because activate ran async-reload
and lost the race with the very next /me call. Sync reload eliminates
the window. ~50ms slower per write, much cleaner.
2026-04-29 18:13:15 +03:00
Claude
6fd12d477b tower 0.58.1 — fix signup race: issue OTP without snap-reload gate 2026-04-29 18:08:42 +03:00
Claude
81841e542b tower 0.58.0 — Phase D: landing + signup + tenantless onboarding
- public POST /api/auth/signup + magic-link verify activates pending users
- POST /api/me/tenants — tenantless self-tenant creation
- /me.tenantless flag drives /welcome routing
- resolveEffectiveTenant picks user's primary tenant when JWT drifts
- new LandingView, SignupView, WelcomeView (lazy-loaded)
- LoginView simplified to magic-link only
2026-04-29 17:25:29 +03:00
Claude
2d9d7a52ed tower 0.57.10 — Phase C: per-tenant Cloudflare DNS lifecycle 2026-04-29 16:55:55 +03:00
Claude
902abb6254 tower 0.57.9 / tower-ui 0.57.11
- relax last-owner guard for super-admin in RemoveMember
- add DELETE /api/users/{id} + admin Users delete button (cascade memberships + grants)
2026-04-29 16:47:49 +03:00
pro-777
ede480f9eb tower: 0.57.7→0.57.8 / tower-ui: 0.57.9→0.57.10 (Delete tenant + capacity graceful) 2026-04-29 15:57:38 +03:00
pro-777
0877602eba tower: 0.57.6→0.57.7 / tower-ui: 0.57.8→0.57.9 (B4: Argo health badge on Server card) 2026-04-29 15:42:14 +03:00
pro-777
fe7e2cb093 tower: 0.57.5 → 0.57.6 (B3: trim bootstrap.sh + share prepareCluster) 2026-04-29 15:33:46 +03:00
pro-777
319da7d043 tower: 0.57.4 → 0.57.5 (B2: SubmitConnect orchestrates per-tenant prepare) 2026-04-29 15:24:59 +03:00
pro-777
1a53cd74be tower-ui: 0.57.7 → 0.57.8 (Tenant Settings tab) 2026-04-29 15:02:10 +03:00
pro-777
797832cd61 tower: 0.57.3 → 0.57.4 (per-tenant settings API) 2026-04-29 14:30:15 +03:00
pro-777
1834c5a944 tower: 0.57.2 → 0.57.3 (Connect trailer: IPv4 + check Tower status) 2026-04-29 14:05:44 +03:00
pro-777
1344f2638c tower: 0.57.1→0.57.2 / tower-ui: 0.57.6→0.57.7 (Disconnect cluster-loop + UX) 2026-04-29 13:45:17 +03:00
pro-777
87ab9655b0 tower-ui: 0.57.5 → 0.57.6 (api.ts authFetch fix for 401s) 2026-04-29 11:46:06 +03:00
pro-777
4709f97420 tower-ui: 0.57.4 → 0.57.5 (merge /activity + /admin/audit) 2026-04-29 11:20:28 +03:00
pro-777
ebcc715434 tower-ui: 0.57.2 → 0.57.4 (useReshape + useMfaEnrollment composables) 2026-04-29 11:14:46 +03:00
pro-777
70a6ce990d tower-ui: 0.57.0 → 0.57.2 (useInstance composable refactor) 2026-04-29 11:07:12 +03:00
4ff3315bc2 ship: tower 0.57.0 -> 0.57.1 (ServeMux pattern conflict fix)
0.57.0 had a Go ServeMux ambiguity between /api/servers/{name}/capacity and /api/servers/connect-token/{token}. Moved the new endpoints to /api/connect-tokens/* to break the wildcard collision.
2026-04-29 07:55:04 +00:00