mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-17 12:46:59 +00:00
* volume: gate the admin RPCs that only shell and workers call checkGrpcAdminAuth covered 19 of the 48 VolumeServer RPCs, so an operator who sets -whiteList expecting it to cover the gRPC surface gets partial coverage. Extend it to ten that mutate state and are only ever called by the shell or a worker: SetState, VolumeCopy, the EC generate/rebuild/copy/unmount/to-volume pair, both tier moves, and VolumeTailReceiver. That is safe because the same callers already reach gated RPCs today -- VolumeMarkReadonly, VacuumVolume*, VolumeEcShardsDelete, VolumeDelete -- so a whitelist deployment already lists those hosts. Nothing here is on a master or peer path, which is what made the earlier fail-closed gate break multi-host clusters. The split is by caller rather than by blast radius: the guard matches a peer IP against the whitelist, and a whitelist holds masters, shell hosts and workers, not every peer volume server. Gating a call one volume server makes to another would break replication, EC and tiering, so those stay open. Two test fakes embedded a nil grpc.ServerStream and only implemented Send; they now implement Context, which the streaming RPCs read to authorize. * volume: fail the build when a gRPC method skips the admin gate The admin gate is an opt-in list in a 48-method service, which is how it drifted down to covering 19 of them: nothing tied adding an RPC to deciding whether it needed the gate. Parse volume_server.proto, walk the AST of every *VolumeServer method, and require each RPC to either call checkGrpcAdminAuth or appear in ungatedVolumeServerRPCs with the reason it stays open. A stale entry naming an RPC that no longer exists fails too, so the list can't quietly stop exempting anything. The exemptions are the cluster-internal calls -- replica sync, EC shard distribution, vacuum reads, backup, tailing -- plus the read-only and liveness RPCs. Closing the cluster-internal ones needs a peer identity rather than an IP whitelist; recording them here makes that a visible decision instead of an omission. The AST walk also corrects the count: a line-window scan credits VacuumVolumeCheck and VolumeServerStatus with a neighbouring function's guard.
30 lines
809 B
Go
30 lines
809 B
Go
package weed_server
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
|
|
)
|
|
|
|
// GetState returns a volume server's state flags.
|
|
func (vs *VolumeServer) GetState(ctx context.Context, req *volume_server_pb.GetStateRequest) (*volume_server_pb.GetStateResponse, error) {
|
|
resp := &volume_server_pb.GetStateResponse{
|
|
State: vs.store.State.Proto(),
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// SetState updates state flags for volume servers.
|
|
func (vs *VolumeServer) SetState(ctx context.Context, req *volume_server_pb.SetStateRequest) (*volume_server_pb.SetStateResponse, error) {
|
|
if err := vs.checkGrpcAdminAuth(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
err := vs.store.State.Update(req.GetState())
|
|
resp := &volume_server_pb.SetStateResponse{
|
|
State: vs.store.State.Proto(),
|
|
}
|
|
|
|
return resp, err
|
|
}
|