diff --git a/admin/internal/inject/inject.go b/admin/internal/inject/inject.go index 23bec5b..a1029dc 100644 --- a/admin/internal/inject/inject.go +++ b/admin/internal/inject/inject.go @@ -7,6 +7,7 @@ package inject import ( "context" + "errors" "fmt" "log" "time" @@ -16,6 +17,7 @@ import ( "github.com/mrhid6/vantage/shared/license" sharedmodels "github.com/mrhid6/vantage/shared/models" "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" ) // ReconcileInterval is how often every cloud instance is compared against what @@ -103,6 +105,19 @@ func Reconcile(ctx context.Context) (checked, repaired int, err error) { var remote sharedmodels.Instance if err := db.Control("instances").FindOne(ctx, bson.M{"instance_id": inst.InstanceID}).Decode(&remote); err != nil { + // The control plane's reaper deletes lapsed Free instances. Record + // that here rather than re-logging it every fifteen minutes forever, + // and so the lifecycle sweep stops emailing about it. + if errors.Is(err, mongo.ErrNoDocuments) { + if _, uErr := db.Admin("admin_instances").UpdateOne(ctx, + bson.M{"instance_id": inst.InstanceID}, + bson.M{"$set": bson.M{"status": models.StatusDeleted}}); uErr != nil { + log.Printf("reconcile: mark %s deleted: %v", inst.InstanceID, uErr) + } else { + log.Printf("reconcile: instance %s is gone from the control plane; marked deleted", inst.InstanceID) + } + continue + } log.Printf("reconcile: no control-plane instance %s: %v", inst.InstanceID, err) continue }