refactor(server): rename Org to Instance

Adds migration 0004_org_to_instance, the ScopedCollections list, the
AssertNoScopedCollectionMissed boot check, and moves EnsureAuthIndexes into
its own file.

Two ordering constraints the rename exposed, both now enforced and commented:

- 0004 must run BEFORE EnsureAuthIndexes. The index builder creates
  instances.slug, which would create an empty instances collection and make
  0004 refuse to rename orgs onto an existing target.
- Migrations 0001 to 0003 run BEFORE 0004 and still read and write org_id, so
  they use a private legacyOrg struct rather than shared/models.
This commit is contained in:
2026-07-24 13:58:41 +01:00
parent 43a2fdb3a0
commit 4f041d2f4b
61 changed files with 895 additions and 967 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ import (
type Assignment struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
KeyID string `bson:"key_id" json:"key_id"`
ServerID string `bson:"server_id" json:"server_id"`
AssignedAt time.Time `bson:"assigned_at" json:"assigned_at"`
+8 -8
View File
@@ -7,12 +7,12 @@ import (
)
type AuditEvent struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"id"`
OrgID string `bson:"org_id" json:"org_id"`
EventType string `bson:"event_type" json:"event_type"`
Actor string `bson:"actor" json:"actor"`
ServerID string `bson:"server_id,omitempty" json:"server_id,omitempty"`
KeyID string `bson:"key_id,omitempty" json:"key_id,omitempty"`
Details string `bson:"details" json:"details"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
ID bson.ObjectID `bson:"_id,omitempty" json:"id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
EventType string `bson:"event_type" json:"event_type"`
Actor string `bson:"actor" json:"actor"`
ServerID string `bson:"server_id,omitempty" json:"server_id,omitempty"`
KeyID string `bson:"key_id,omitempty" json:"key_id,omitempty"`
Details string `bson:"details" json:"details"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
}
+8 -12
View File
@@ -6,7 +6,6 @@ import (
"go.mongodb.org/mongo-driver/v2/bson"
)
const (
ChannelWebhook = "webhook"
ChannelSMTP = "smtp"
@@ -15,16 +14,13 @@ const (
ChannelTelegram = "telegram"
)
type NotificationChannel struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
ChannelID string `bson:"channel_id" json:"channel_id"`
Name string `bson:"name" json:"name"`
Type string `bson:"type" json:"type"`
Config map[string]string `bson:"config" json:"config"`
Enabled bool `bson:"enabled" json:"enabled"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
InstanceID string `bson:"instance_id" json:"instance_id"`
ChannelID string `bson:"channel_id" json:"channel_id"`
Name string `bson:"name" json:"name"`
Type string `bson:"type" json:"type"`
Config map[string]string `bson:"config" json:"config"`
Enabled bool `bson:"enabled" json:"enabled"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
}
+10 -12
View File
@@ -7,19 +7,17 @@ import (
)
type ConsoleSession struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
SessionID string `bson:"session_id" json:"session_id"`
ServerID string `bson:"server_id" json:"server_id"`
Protocol string `bson:"protocol" json:"protocol"`
KeyID string `bson:"key_id,omitempty" json:"key_id,omitempty"`
User string `bson:"user" json:"user"`
StartedAt time.Time `bson:"started_at" json:"started_at"`
EndedAt *time.Time `bson:"ended_at,omitempty" json:"ended_at,omitempty"`
ClientIP string `bson:"client_ip,omitempty" json:"client_ip,omitempty"`
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
InstanceID string `bson:"instance_id" json:"instance_id"`
SessionID string `bson:"session_id" json:"session_id"`
ServerID string `bson:"server_id" json:"server_id"`
Protocol string `bson:"protocol" json:"protocol"`
KeyID string `bson:"key_id,omitempty" json:"key_id,omitempty"`
User string `bson:"user" json:"user"`
StartedAt time.Time `bson:"started_at" json:"started_at"`
EndedAt *time.Time `bson:"ended_at,omitempty" json:"ended_at,omitempty"`
ClientIP string `bson:"client_ip,omitempty" json:"client_ip,omitempty"`
TokenConsumedAt *time.Time `bson:"token_consumed_at,omitempty" json:"-"`
SSHUsername string `bson:"ssh_username,omitempty" json:"ssh_username,omitempty"`
+7
View File
@@ -0,0 +1,7 @@
package models
import shared "github.com/mrhid6/vantage/shared/models"
// Instance is defined in the shared module because sitesvc and the admin
// control plane write the same documents.
type Instance = shared.Instance
+2 -2
View File
@@ -8,12 +8,12 @@ import (
type Key struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
KeyID string `bson:"key_id" json:"key_id"`
Label string `bson:"label" json:"label"`
PublicKey string `bson:"public_key" json:"public_key"`
Fingerprint string `bson:"fingerprint" json:"fingerprint"`
Source string `bson:"source" json:"source"`
Source string `bson:"source" json:"source"`
GeneratedByServerID string `bson:"generated_by_server_id,omitempty" json:"generated_by_server_id,omitempty"`
PrivateKeyEncrypted string `bson:"private_key_enc,omitempty" json:"-"`
HasPrivateKey bool `bson:"-" json:"has_private_key"`
+10 -14
View File
@@ -6,7 +6,6 @@ import (
"go.mongodb.org/mongo-driver/v2/bson"
)
const (
MonitorHTTP = "http"
MonitorTCP = "tcp"
@@ -14,15 +13,12 @@ const (
MonitorTLS = "tls"
)
const (
StatusUp = "up"
StatusDown = "down"
StatusPending = "pending"
)
const RunnerServer = "server"
type MonitorTarget struct {
@@ -33,29 +29,29 @@ type MonitorTarget struct {
ExpectedStatus int `bson:"expected_status,omitempty" json:"expected_status,omitempty"`
Keyword string `bson:"keyword,omitempty" json:"keyword,omitempty"`
TLSWarnDays int `bson:"tls_warn_days,omitempty" json:"tls_warn_days,omitempty"`
Insecure bool `bson:"insecure,omitempty" json:"insecure,omitempty"`
Insecure bool `bson:"insecure,omitempty" json:"insecure,omitempty"`
}
type MonitorState struct {
Status string `bson:"status" json:"status"`
Status string `bson:"status" json:"status"`
LastCheckAt *time.Time `bson:"last_check_at,omitempty" json:"last_check_at,omitempty"`
LatencyMs int `bson:"latency_ms" json:"latency_ms"`
Message string `bson:"message,omitempty" json:"message,omitempty"`
CertExpiryAt *time.Time `bson:"cert_expiry_at,omitempty" json:"cert_expiry_at,omitempty"`
Fails int `bson:"fails" json:"fails"`
Fails int `bson:"fails" json:"fails"`
LastNotifiedAt *time.Time `bson:"last_notified_at,omitempty" json:"last_notified_at,omitempty"`
}
type Monitor struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
MonitorID string `bson:"monitor_id" json:"monitor_id"`
Name string `bson:"name" json:"name"`
Type string `bson:"type" json:"type"`
Type string `bson:"type" json:"type"`
Target MonitorTarget `bson:"target" json:"target"`
IntervalSec int `bson:"interval_sec" json:"interval_sec"`
Runner string `bson:"runner" json:"runner"`
Retries int `bson:"retries" json:"retries"`
Runner string `bson:"runner" json:"runner"`
Retries int `bson:"retries" json:"retries"`
Enabled bool `bson:"enabled" json:"enabled"`
ChannelIDs []string `bson:"channel_ids,omitempty" json:"channel_ids,omitempty"`
State MonitorState `bson:"state" json:"state"`
@@ -63,7 +59,7 @@ type Monitor struct {
}
type Incident struct {
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
IncidentID string `bson:"incident_id" json:"incident_id"`
MonitorID string `bson:"monitor_id" json:"monitor_id"`
StartedAt time.Time `bson:"started_at" json:"started_at"`
@@ -72,9 +68,9 @@ type Incident struct {
}
type Rollup struct {
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
MonitorID string `bson:"monitor_id" json:"monitor_id"`
PeriodStart time.Time `bson:"period_start" json:"period_start"`
PeriodStart time.Time `bson:"period_start" json:"period_start"`
Checks int `bson:"checks" json:"checks"`
UpCount int `bson:"up_count" json:"up_count"`
SumLatency int64 `bson:"sum_latency" json:"sum_latency"`
-8
View File
@@ -1,8 +0,0 @@
package models
import shared "github.com/mrhid6/vantage/shared/models"
// Org is defined in the shared module because sitesvc writes the same
// documents. Aliased rather than re-declared so existing call sites are
// unchanged and the two services cannot drift.
type Org = shared.Org
+1 -1
View File
@@ -8,7 +8,7 @@ import (
type OrgOIDC struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
Issuer string `bson:"issuer" json:"issuer"`
ClientID string `bson:"client_id" json:"client_id"`
ClientSecretEnc string `bson:"client_secret_enc,omitempty" json:"-"`
+1 -4
View File
@@ -6,18 +6,15 @@ import (
"go.mongodb.org/mongo-driver/v2/bson"
)
type Secret struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
Group string `bson:"group" json:"group"`
Key string `bson:"key" json:"key"`
EncryptedValue string `bson:"encrypted_value" json:"-"`
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
}
type GroupSummary struct {
Group string `json:"group"`
KeyCount int `json:"key_count"`
+1 -1
View File
@@ -45,7 +45,7 @@ type Inventory struct {
type Server struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"_id,omitempty"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
ServerID string `bson:"server_id" json:"server_id"`
Hostname string `bson:"hostname" json:"hostname"`
IPAddress string `bson:"ip_address" json:"ip_address"`
+9 -10
View File
@@ -14,16 +14,16 @@ type InputParam struct {
type WorkflowStep struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
StepID string `bson:"step_id" json:"step_id"`
Name string `bson:"name" json:"name"`
Description string `bson:"description" json:"description"`
Interpreter string `bson:"interpreter" json:"interpreter"`
Interpreter string `bson:"interpreter" json:"interpreter"`
Script string `bson:"script" json:"script"`
DeclaredOutputs []string `bson:"declared_outputs" json:"declared_outputs"`
DeclaredInputs []InputParam `bson:"declared_inputs" json:"declared_inputs"`
SecretRefs []string `bson:"secret_refs" json:"secret_refs"`
Source string `bson:"source" json:"source"`
Source string `bson:"source" json:"source"`
Slug string `bson:"slug,omitempty" json:"slug,omitempty"`
CreatedAt time.Time `bson:"created_at" json:"created_at"`
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
@@ -33,7 +33,7 @@ type WorkflowStepRef struct {
StepID string `bson:"step_id,omitempty" json:"step_id,omitempty"`
Inline *WorkflowStep `bson:"inline,omitempty" json:"inline,omitempty"`
Order int `bson:"order" json:"order"`
OnFailure string `bson:"on_failure" json:"on_failure"`
OnFailure string `bson:"on_failure" json:"on_failure"`
MaxRetries int `bson:"max_retries" json:"max_retries"`
Overrides *StepOverride `bson:"overrides,omitempty" json:"overrides,omitempty"`
Inputs map[string]string `bson:"inputs,omitempty" json:"inputs,omitempty"`
@@ -46,7 +46,7 @@ type StepOverride struct {
type Workflow struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
WorkflowID string `bson:"workflow_id" json:"workflow_id"`
Name string `bson:"name" json:"name"`
TargetServerIDs []string `bson:"target_server_ids" json:"target_server_ids"`
@@ -55,7 +55,6 @@ type Workflow struct {
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
}
type ResolvedStep struct {
Order int `bson:"order" json:"order"`
Name string `bson:"name" json:"name"`
@@ -70,7 +69,7 @@ type ResolvedStep struct {
type StepRun struct {
Order int `bson:"order" json:"order"`
Name string `bson:"name" json:"name"`
Status string `bson:"status" json:"status"`
Status string `bson:"status" json:"status"`
Attempts int `bson:"attempts" json:"attempts"`
ExitCode int `bson:"exit_code" json:"exit_code"`
LogOffset int64 `bson:"log_offset" json:"log_offset"`
@@ -82,7 +81,7 @@ type StepRun struct {
type ServerRun struct {
ServerID string `bson:"server_id" json:"server_id"`
Hostname string `bson:"hostname" json:"hostname"`
Status string `bson:"status" json:"status"`
Status string `bson:"status" json:"status"`
StartedAt *time.Time `bson:"started_at,omitempty" json:"started_at,omitempty"`
FinishedAt *time.Time `bson:"finished_at,omitempty" json:"finished_at,omitempty"`
RunEnv map[string]string `bson:"run_env" json:"run_env"`
@@ -91,12 +90,12 @@ type ServerRun struct {
type WorkflowRun struct {
ID bson.ObjectID `bson:"_id,omitempty" json:"-"`
OrgID string `bson:"org_id" json:"org_id"`
InstanceID string `bson:"instance_id" json:"instance_id"`
RunID string `bson:"run_id" json:"run_id"`
WorkflowID string `bson:"workflow_id" json:"workflow_id"`
Name string `bson:"name" json:"name"`
Steps []ResolvedStep `bson:"steps_snapshot" json:"steps_snapshot"`
Status string `bson:"status" json:"status"`
Status string `bson:"status" json:"status"`
TriggeredBy string `bson:"triggered_by" json:"triggered_by"`
StartedAt time.Time `bson:"started_at" json:"started_at"`
FinishedAt *time.Time `bson:"finished_at,omitempty" json:"finished_at,omitempty"`