-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC, WIP: etcdserver: let maintenance services require root role #6898
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ import ( | |
"crypto/sha256" | ||
"io" | ||
|
||
"github.com/coreos/etcd/auth" | ||
"github.com/coreos/etcd/etcdserver" | ||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" | ||
"github.com/coreos/etcd/mvcc" | ||
|
@@ -45,6 +46,10 @@ type RaftStatusGetter interface { | |
Leader() types.ID | ||
} | ||
|
||
type AuthGetter interface { | ||
AuthStore() auth.AuthStore | ||
} | ||
|
||
type maintenanceServer struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can there be a separate type returned by
that does the auth checks before calling into the auth-free maintenance server? This buys type-checking that auth covers all calls for the service since if it misses a check it won't match the interface. I'd like to avoid mingling auth code with non-auth code if it's not strictly necessary... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, I'll try it |
||
rg RaftStatusGetter | ||
kg KVGetter | ||
|
@@ -54,7 +59,8 @@ type maintenanceServer struct { | |
} | ||
|
||
func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { | ||
return &maintenanceServer{rg: s, kg: s, bg: s, a: s, hdr: newHeader(s)} | ||
srv := &maintenanceServer{rg: s, kg: s, bg: s, a: s, hdr: newHeader(s)} | ||
return &authMaintenanceServer{srv, s} | ||
} | ||
|
||
func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { | ||
|
@@ -139,3 +145,49 @@ func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) ( | |
ms.hdr.fill(resp.Header) | ||
return resp, nil | ||
} | ||
|
||
type authMaintenanceServer struct { | ||
*maintenanceServer | ||
ag AuthGetter | ||
} | ||
|
||
func (ams *authMaintenanceServer) isAuthenticated(ctx context.Context) error { | ||
authInfo, err := ams.ag.AuthStore().AuthInfoFromCtx(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return ams.ag.AuthStore().IsAdminPermitted(authInfo) | ||
} | ||
|
||
func (ams *authMaintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { | ||
if err := ams.isAuthenticated(ctx); err != nil { | ||
return nil, err | ||
} | ||
|
||
return ams.maintenanceServer.Defragment(ctx, sr) | ||
} | ||
|
||
func (ams *authMaintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error { | ||
if err := ams.isAuthenticated(srv.Context()); err != nil { | ||
return err | ||
} | ||
|
||
return ams.maintenanceServer.Snapshot(sr, srv) | ||
} | ||
|
||
func (ams *authMaintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { | ||
if err := ams.isAuthenticated(ctx); err != nil { | ||
return nil, err | ||
} | ||
|
||
return ams.maintenanceServer.Hash(ctx, r) | ||
} | ||
|
||
func (ams *authMaintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { | ||
if err := ams.isAuthenticated(ctx); err != nil { | ||
return nil, err | ||
} | ||
|
||
return ams.maintenanceServer.Status(ctx, ar) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the mention of gRPC? then this interface seems more generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
AuthInfoFromCtx()
, gRPC's metadata is obtained bymetadata.FromContext()
. So I think the context cannot be said generic.