diff --git a/server/internal/grpc/server.go b/server/internal/grpc/server.go index 21a63a4..c279b6d 100644 --- a/server/internal/grpc/server.go +++ b/server/internal/grpc/server.go @@ -43,6 +43,10 @@ func (s *vantageServer) SyncKeys(ctx context.Context, req *pb.SyncRequest) (*pb. log.Printf("failed to update last seen for %s: %v", srv.ServerID, err) } + if err := services.BackfillConsoleConfig(srv); err != nil { + log.Printf("failed to backfill console config for %s: %v", srv.ServerID, err) + } + keys, err := services.BuildAuthorizedKeys(req.ServerId) if err != nil { return nil, status.Errorf(codes.Internal, "failed to build authorized keys: %v", err) diff --git a/server/internal/services/servers.go b/server/internal/services/servers.go index 4a5946c..a6fff8e 100644 --- a/server/internal/services/servers.go +++ b/server/internal/services/servers.go @@ -167,6 +167,37 @@ func ValidateAgentToken(serverID, agentToken string) (*models.Server, error) { return &s, nil } +// BackfillConsoleConfig sets default console_protocols/ports for a server that +// predates the console feature (or was updated without re-registering). Servers +// register only once via a single-use pre_reg_token, so Register() never runs +// again to populate these fields — this runs on every sync as a cheap no-op +// once the fields are present. +func BackfillConsoleConfig(srv *models.Server) error { + if srv == nil || len(srv.ConsoleProtocols) > 0 { + return nil + } + + osType := srv.OSType + if osType == "" { + osType = OSTypeFromInfo(srv.OSInfo) + } + protocols, sshPort, rdpPort := defaultConsoleFields(osType) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + _, err := db.Col("servers").UpdateOne(ctx, + bson.M{"server_id": srv.ServerID, "console_protocols": bson.M{"$in": []interface{}{nil, bson.A{}}}}, + bson.M{"$set": bson.M{ + "os_type": osType, + "console_protocols": protocols, + "ssh_port": sshPort, + "rdp_port": rdpPort, + }}, + ) + return err +} + func UpdateServerLastSeen(serverID, agentVersion string) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel()