diff --git a/weed/command/filer.go b/weed/command/filer.go index 64d227b95..c730c097d 100644 --- a/weed/command/filer.go +++ b/weed/command/filer.go @@ -22,6 +22,7 @@ import ( "github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" "github.com/seaweedfs/seaweedfs/weed/security" weed_server "github.com/seaweedfs/seaweedfs/weed/server" stats_collect "github.com/seaweedfs/seaweedfs/weed/stats" @@ -389,6 +390,7 @@ func (fo *FilerOptions) startFiler() { } grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer")) filer_pb.RegisterSeaweedFilerServer(grpcS, fs) + iam_pb.RegisterSeaweedIdentityAccessManagementServer(grpcS, fs) reflection.Register(grpcS) if grpcLocalL != nil { go grpcS.Serve(grpcLocalL) diff --git a/weed/server/filer_grpc_server_iam.go b/weed/server/filer_grpc_server_iam.go new file mode 100644 index 000000000..a5225bac8 --- /dev/null +++ b/weed/server/filer_grpc_server_iam.go @@ -0,0 +1,35 @@ +package weed_server + +import ( + "context" + + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// GetS3ApiConfiguration returns the full S3 API configuration stored in the credential store. +func (fs *FilerServer) GetS3ApiConfiguration(ctx context.Context, req *iam_pb.GetS3ApiConfigurationRequest) (*iam_pb.GetS3ApiConfigurationResponse, error) { + if fs.credentialManager == nil { + return nil, status.Error(codes.FailedPrecondition, "credential manager not initialized") + } + config, err := fs.credentialManager.LoadConfiguration(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "load S3 configuration: %v", err) + } + return &iam_pb.GetS3ApiConfigurationResponse{Config: config}, nil +} + +// PutS3ApiConfiguration persists the full S3 API configuration to the credential store. +func (fs *FilerServer) PutS3ApiConfiguration(ctx context.Context, req *iam_pb.PutS3ApiConfigurationRequest) (*iam_pb.PutS3ApiConfigurationResponse, error) { + if fs.credentialManager == nil { + return nil, status.Error(codes.FailedPrecondition, "credential manager not initialized") + } + if req.GetConfig() == nil { + return nil, status.Error(codes.InvalidArgument, "config is required") + } + if err := fs.credentialManager.SaveConfiguration(ctx, req.GetConfig()); err != nil { + return nil, status.Errorf(codes.Internal, "save S3 configuration: %v", err) + } + return &iam_pb.PutS3ApiConfigurationResponse{}, nil +} diff --git a/weed/server/filer_server.go b/weed/server/filer_server.go index 57fd7ab25..5830b6cea 100644 --- a/weed/server/filer_server.go +++ b/weed/server/filer_server.go @@ -20,9 +20,11 @@ import ( "github.com/seaweedfs/seaweedfs/weed/operation" "github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" "github.com/seaweedfs/seaweedfs/weed/pb/master_pb" "github.com/seaweedfs/seaweedfs/weed/util" + "github.com/seaweedfs/seaweedfs/weed/credential" "github.com/seaweedfs/seaweedfs/weed/filer" _ "github.com/seaweedfs/seaweedfs/weed/filer/arangodb" _ "github.com/seaweedfs/seaweedfs/weed/filer/cassandra" @@ -95,12 +97,14 @@ type FilerServer struct { inFlightDataLimitCond *sync.Cond filer_pb.UnimplementedSeaweedFilerServer - option *FilerOption - secret security.SigningKey - filer *filer.Filer - filerGuard *security.Guard - volumeGuard *security.Guard - grpcDialOption grpc.DialOption + iam_pb.UnimplementedSeaweedIdentityAccessManagementServer + option *FilerOption + secret security.SigningKey + filer *filer.Filer + filerGuard *security.Guard + volumeGuard *security.Guard + grpcDialOption grpc.DialOption + credentialManager *credential.CredentialManager // metrics read from the master metricsAddress string @@ -149,6 +153,23 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) knownListeners: make(map[int32]int32), inFlightDataLimitCond: sync.NewCond(new(sync.Mutex)), } + + credentialManager, credErr := credential.NewCredentialManagerWithDefaults("") + if credErr != nil { + glog.Warningf("Failed to initialize credential manager: %v", credErr) + } else { + fs.credentialManager = credentialManager + if store := credentialManager.GetStore(); store != nil { + if filerFuncSetter, ok := store.(interface { + SetFilerAddressFunc(func() pb.ServerAddress, grpc.DialOption) + }); ok { + filerFuncSetter.SetFilerAddressFunc(func() pb.ServerAddress { + return fs.option.Host + }, fs.grpcDialOption) + glog.V(1).Infof("Credential store configured with local filer address for IAM gRPC") + } + } + } fs.listenersCond = sync.NewCond(&fs.listenersLock) option.Masters.RefreshBySrvIfAvailable()