1
0
mirror of https://github.com/lxc/incus.git synced 2026-02-05 09:46:19 +01:00

incusd/cluster: Restrict join token to database servers

This avoids generating a huge token on very large clusters.

Closes #2886

Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
This commit is contained in:
Stéphane Graber
2026-02-04 16:48:36 +01:00
parent 80a5519509
commit b2a41e7b9f

View File

@@ -1366,24 +1366,79 @@ func clusterNodesPost(d *Daemon, r *http.Request) response.Response {
// retrieving remote operations.
onlineNodeAddresses := make([]any, 0)
// Get cluster database state.
leaderAddress, err := s.Cluster.LeaderAddress()
if err != nil {
return response.InternalError(err)
}
var raftNodes []db.RaftNode
err = s.DB.Node.Transaction(r.Context(), func(ctx context.Context, tx *db.NodeTx) error {
raftNodes, err = tx.GetRaftNodes(ctx)
if err != nil {
return fmt.Errorf("Failed loading RAFT nodes: %w", err)
}
return nil
})
if err != nil {
return response.SmartError(err)
}
err = s.DB.Cluster.Transaction(r.Context(), func(ctx context.Context, tx *db.ClusterTx) error {
// Get global cluster state.
failureDomains, err := tx.GetFailureDomainsNames(ctx)
if err != nil {
return fmt.Errorf("Failed loading failure domains names: %w", err)
}
memberFailureDomains, err := tx.GetNodesFailureDomains(ctx)
if err != nil {
return fmt.Errorf("Failed loading member failure domains: %w", err)
}
maxVersion, err := tx.GetNodeMaxVersion(ctx)
if err != nil {
return fmt.Errorf("Failed getting max member version: %w", err)
}
// Get the nodes.
members, err := tx.GetNodes(ctx)
if err != nil {
return fmt.Errorf("Failed getting cluster members: %w", err)
}
args := db.NodeInfoArgs{
LeaderAddress: leaderAddress,
FailureDomains: failureDomains,
MemberFailureDomains: memberFailureDomains,
OfflineThreshold: s.GlobalConfig.OfflineThreshold(),
MaxMemberVersion: maxVersion,
RaftNodes: raftNodes,
}
// Filter to online members.
for _, member := range members {
memberInfo, err := member.ToAPI(ctx, tx, args)
if err != nil {
return err
}
// Verify if a node with the same name already exists in the cluster.
if member.Name == req.ServerName {
return fmt.Errorf("The cluster already has a member with name: %s", req.ServerName)
}
// Skip servers that are offline.
if member.State == db.ClusterMemberStateEvacuated || member.IsOffline(s.GlobalConfig.OfflineThreshold()) {
continue
}
// Only include servers that have a one of the database roles.
if !slices.Contains(memberInfo.Roles, "database") && !slices.Contains(memberInfo.Roles, "database-standby") {
continue
}
onlineNodeAddresses = append(onlineNodeAddresses, member.Address)
}