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:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user