feat: patch models, scoped collections and indexes; pin vantage-shared v0.5.0
This commit is contained in:
@@ -48,6 +48,9 @@ var ScopedCollections = []string{
|
||||
"server_workloads",
|
||||
"status_pages",
|
||||
"status_incidents",
|
||||
"maintenance_windows",
|
||||
"patch_policies",
|
||||
"patch_runs",
|
||||
}
|
||||
|
||||
// collectionRenames maps the two collections whose names change. Ordered so the
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/db"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
)
|
||||
|
||||
// EnsurePatchIndexes builds the patching indexes. The command_id index is the
|
||||
// one that matters: every PatchResult is matched to its server run through it.
|
||||
func EnsurePatchIndexes() error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if _, err := db.Col("maintenance_windows").Indexes().CreateOne(ctx, mongo.IndexModel{
|
||||
Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "window_id", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.Col("patch_policies").Indexes().CreateMany(ctx, []mongo.IndexModel{
|
||||
{Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "policy_id", Value: 1}}, Options: options.Index().SetUnique(true)},
|
||||
{Keys: bson.D{{Key: "enabled", Value: 1}, {Key: "next_run_at", Value: 1}}},
|
||||
{Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "window_id", Value: 1}}},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := db.Col("patch_runs").Indexes().CreateMany(ctx, []mongo.IndexModel{
|
||||
{Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "run_id", Value: 1}}, Options: options.Index().SetUnique(true)},
|
||||
{Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "policy_id", Value: 1}, {Key: "started_at", Value: -1}}},
|
||||
{Keys: bson.D{{Key: "instance_id", Value: 1}, {Key: "servers.server_id", Value: 1}, {Key: "started_at", Value: -1}}},
|
||||
{Keys: bson.D{{Key: "status", Value: 1}}},
|
||||
{Keys: bson.D{{Key: "servers.command_id", Value: 1}}},
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package services
|
||||
|
||||
import "testing"
|
||||
|
||||
// A tenant-scoped collection missing from ScopedCollections outlives its
|
||||
// instance when the instance is purged.
|
||||
func TestPatchCollectionsAreScoped(t *testing.T) {
|
||||
for _, name := range []string{"maintenance_windows", "patch_policies", "patch_runs"} {
|
||||
found := false
|
||||
for _, got := range ScopedCollections {
|
||||
if got == name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("ScopedCollections is missing %q", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user