Compare commits

...
Author SHA1 Message Date
Chris Lu dcc44b5ed3 Regenerate IAM protobuf with gRPC service methods 2026-01-25 00:49:18 -08:00
Chris Lu 5798b6bc3a Wire IAM gRPC service to filer server
- Add CredentialManager field to FilerOption and FilerServer
- Import credential store implementations in filer command
- Initialize CredentialManager from credential.toml if available
- Register IAM gRPC service on filer gRPC server
- Enable credential management via gRPC alongside existing filer services
2026-01-25 00:48:24 -08:00
Chris Lu ad306519d7 Add IAM gRPC handlers on filer server
- Implement IamGrpcServer with CredentialManager integration
- Handle configuration get/put operations
- Handle user CRUD operations
- Handle access key create/delete operations
- All methods delegate to CredentialManager for actual storage
2026-01-25 00:48:19 -08:00
Chris Lu 94157f4bb3 Add IAM gRPC service definition
- Add GetConfiguration/PutConfiguration for config management
- Add CreateUser/GetUser/UpdateUser/DeleteUser/ListUsers for user management
- Add CreateAccessKey/DeleteAccessKey/GetUserByAccessKey for access key management
- Methods mirror existing IAM HTTP API functionality
2026-01-25 00:48:11 -08:00
6 changed files with 1714 additions and 44 deletions
+32
View File
@@ -18,10 +18,15 @@ import (
"google.golang.org/grpc/credentials/tls/certprovider/pemfile"
"google.golang.org/grpc/reflection"
"github.com/seaweedfs/seaweedfs/weed/credential"
_ "github.com/seaweedfs/seaweedfs/weed/credential/filer_etc"
_ "github.com/seaweedfs/seaweedfs/weed/credential/memory"
_ "github.com/seaweedfs/seaweedfs/weed/credential/postgres"
"github.com/seaweedfs/seaweedfs/weed/filer"
"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"
@@ -324,6 +329,24 @@ func (fo *FilerOptions) startFiler() {
filerAddress := pb.NewServerAddress(*fo.ip, *fo.port, *fo.portGrpc)
// Initialize credential manager for IAM gRPC service
var credentialManager *credential.CredentialManager
credConfig, err := credential.LoadCredentialConfiguration()
if err == nil && credConfig != nil {
credentialManager, err = credential.NewCredentialManager(
credential.CredentialStoreTypeName(credConfig.Store),
credConfig.Config,
credConfig.Prefix,
)
if err != nil {
glog.Warningf("Failed to initialize credential manager: %v", err)
} else {
glog.V(0).Infof("Initialized credential manager with store: %s", credConfig.Store)
}
} else {
glog.V(1).Info("No credential store configured for filer")
}
fs, nfs_err := weed_server.NewFilerServer(defaultMux, publicVolumeMux, &weed_server.FilerOption{
Masters: fo.masters,
FilerGroup: *fo.filerGroup,
@@ -346,6 +369,7 @@ func (fo *FilerOptions) startFiler() {
DiskType: *fo.diskType,
AllowedOrigins: strings.Split(*fo.allowedOrigins, ","),
TusBasePath: *fo.tusBasePath,
CredentialManager: credentialManager,
})
if nfs_err != nil {
glog.Fatalf("Filer startup error: %v", nfs_err)
@@ -389,6 +413,14 @@ func (fo *FilerOptions) startFiler() {
}
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer"))
filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
// Register IAM gRPC service if credential manager is available
if credentialManager != nil {
iamGrpcServer := weed_server.NewIamGrpcServer(credentialManager)
iam_pb.RegisterSeaweedIdentityAccessManagementServer(grpcS, iamGrpcServer)
glog.V(0).Info("Registered IAM gRPC service on filer")
}
reflection.Register(grpcS)
if grpcLocalL != nil {
go grpcS.Serve(grpcLocalL)
+98
View File
@@ -9,7 +9,105 @@ option java_outer_classname = "IamProto";
//////////////////////////////////////////////////
service SeaweedIdentityAccessManagement {
// Configuration Management
rpc GetConfiguration (GetConfigurationRequest) returns (GetConfigurationResponse);
rpc PutConfiguration (PutConfigurationRequest) returns (PutConfigurationResponse);
// User Management
rpc CreateUser (CreateUserRequest) returns (CreateUserResponse);
rpc GetUser (GetUserRequest) returns (GetUserResponse);
rpc UpdateUser (UpdateUserRequest) returns (UpdateUserResponse);
rpc DeleteUser (DeleteUserRequest) returns (DeleteUserResponse);
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
// Access Key Management
rpc CreateAccessKey (CreateAccessKeyRequest) returns (CreateAccessKeyResponse);
rpc DeleteAccessKey (DeleteAccessKeyRequest) returns (DeleteAccessKeyResponse);
rpc GetUserByAccessKey (GetUserByAccessKeyRequest) returns (GetUserByAccessKeyResponse);
}
//////////////////////////////////////////////////
// Configuration Management Messages
message GetConfigurationRequest {
}
message GetConfigurationResponse {
S3ApiConfiguration configuration = 1;
}
message PutConfigurationRequest {
S3ApiConfiguration configuration = 1;
}
message PutConfigurationResponse {
}
//////////////////////////////////////////////////
// User Management Messages
message CreateUserRequest {
Identity identity = 1;
}
message CreateUserResponse {
}
message GetUserRequest {
string username = 1;
}
message GetUserResponse {
Identity identity = 1;
}
message UpdateUserRequest {
string username = 1;
Identity identity = 2;
}
message UpdateUserResponse {
}
message DeleteUserRequest {
string username = 1;
}
message DeleteUserResponse {
}
message ListUsersRequest {
}
message ListUsersResponse {
repeated string usernames = 1;
}
//////////////////////////////////////////////////
// Access Key Management Messages
message CreateAccessKeyRequest {
string username = 1;
Credential credential = 2;
}
message CreateAccessKeyResponse {
}
message DeleteAccessKeyRequest {
string username = 1;
string access_key = 2;
}
message DeleteAccessKeyResponse {
}
message GetUserByAccessKeyRequest {
string access_key = 1;
}
message GetUserByAccessKeyResponse {
Identity identity = 1;
}
//////////////////////////////////////////////////
+978 -40
View File
File diff suppressed because it is too large Load Diff
+397 -4
View File
@@ -1,13 +1,16 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v6.33.1
// - protoc v6.33.4
// source: iam.proto
package iam_pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
@@ -15,10 +18,36 @@ import (
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
SeaweedIdentityAccessManagement_GetConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetConfiguration"
SeaweedIdentityAccessManagement_PutConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/PutConfiguration"
SeaweedIdentityAccessManagement_CreateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateUser"
SeaweedIdentityAccessManagement_GetUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUser"
SeaweedIdentityAccessManagement_UpdateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/UpdateUser"
SeaweedIdentityAccessManagement_DeleteUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteUser"
SeaweedIdentityAccessManagement_ListUsers_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListUsers"
SeaweedIdentityAccessManagement_CreateAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateAccessKey"
SeaweedIdentityAccessManagement_DeleteAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteAccessKey"
SeaweedIdentityAccessManagement_GetUserByAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUserByAccessKey"
)
// SeaweedIdentityAccessManagementClient is the client API for SeaweedIdentityAccessManagement service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SeaweedIdentityAccessManagementClient interface {
// Configuration Management
GetConfiguration(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error)
PutConfiguration(ctx context.Context, in *PutConfigurationRequest, opts ...grpc.CallOption) (*PutConfigurationResponse, error)
// User Management
CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error)
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error)
DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error)
ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error)
// Access Key Management
CreateAccessKey(ctx context.Context, in *CreateAccessKeyRequest, opts ...grpc.CallOption) (*CreateAccessKeyResponse, error)
DeleteAccessKey(ctx context.Context, in *DeleteAccessKeyRequest, opts ...grpc.CallOption) (*DeleteAccessKeyResponse, error)
GetUserByAccessKey(ctx context.Context, in *GetUserByAccessKeyRequest, opts ...grpc.CallOption) (*GetUserByAccessKeyResponse, error)
}
type seaweedIdentityAccessManagementClient struct {
@@ -29,10 +58,123 @@ func NewSeaweedIdentityAccessManagementClient(cc grpc.ClientConnInterface) Seawe
return &seaweedIdentityAccessManagementClient{cc}
}
func (c *seaweedIdentityAccessManagementClient) GetConfiguration(ctx context.Context, in *GetConfigurationRequest, opts ...grpc.CallOption) (*GetConfigurationResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetConfigurationResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_GetConfiguration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) PutConfiguration(ctx context.Context, in *PutConfigurationRequest, opts ...grpc.CallOption) (*PutConfigurationResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(PutConfigurationResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_PutConfiguration_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CreateUserResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_CreateUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetUserResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_GetUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(UpdateUserResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_UpdateUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DeleteUserResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_DeleteUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListUsersResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_ListUsers_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) CreateAccessKey(ctx context.Context, in *CreateAccessKeyRequest, opts ...grpc.CallOption) (*CreateAccessKeyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(CreateAccessKeyResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_CreateAccessKey_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) DeleteAccessKey(ctx context.Context, in *DeleteAccessKeyRequest, opts ...grpc.CallOption) (*DeleteAccessKeyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DeleteAccessKeyResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_DeleteAccessKey_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedIdentityAccessManagementClient) GetUserByAccessKey(ctx context.Context, in *GetUserByAccessKeyRequest, opts ...grpc.CallOption) (*GetUserByAccessKeyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetUserByAccessKeyResponse)
err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_GetUserByAccessKey_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// SeaweedIdentityAccessManagementServer is the server API for SeaweedIdentityAccessManagement service.
// All implementations must embed UnimplementedSeaweedIdentityAccessManagementServer
// for forward compatibility.
type SeaweedIdentityAccessManagementServer interface {
// Configuration Management
GetConfiguration(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error)
PutConfiguration(context.Context, *PutConfigurationRequest) (*PutConfigurationResponse, error)
// User Management
CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error)
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error)
DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error)
ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error)
// Access Key Management
CreateAccessKey(context.Context, *CreateAccessKeyRequest) (*CreateAccessKeyResponse, error)
DeleteAccessKey(context.Context, *DeleteAccessKeyRequest) (*DeleteAccessKeyResponse, error)
GetUserByAccessKey(context.Context, *GetUserByAccessKeyRequest) (*GetUserByAccessKeyResponse, error)
mustEmbedUnimplementedSeaweedIdentityAccessManagementServer()
}
@@ -43,6 +185,36 @@ type SeaweedIdentityAccessManagementServer interface {
// pointer dereference when methods are called.
type UnimplementedSeaweedIdentityAccessManagementServer struct{}
func (UnimplementedSeaweedIdentityAccessManagementServer) GetConfiguration(context.Context, *GetConfigurationRequest) (*GetConfigurationResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetConfiguration not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) PutConfiguration(context.Context, *PutConfigurationRequest) (*PutConfigurationResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PutConfiguration not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListUsers not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) CreateAccessKey(context.Context, *CreateAccessKeyRequest) (*CreateAccessKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateAccessKey not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) DeleteAccessKey(context.Context, *DeleteAccessKeyRequest) (*DeleteAccessKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteAccessKey not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) GetUserByAccessKey(context.Context, *GetUserByAccessKeyRequest) (*GetUserByAccessKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserByAccessKey not implemented")
}
func (UnimplementedSeaweedIdentityAccessManagementServer) mustEmbedUnimplementedSeaweedIdentityAccessManagementServer() {
}
func (UnimplementedSeaweedIdentityAccessManagementServer) testEmbeddedByValue() {}
@@ -65,13 +237,234 @@ func RegisterSeaweedIdentityAccessManagementServer(s grpc.ServiceRegistrar, srv
s.RegisterService(&SeaweedIdentityAccessManagement_ServiceDesc, srv)
}
func _SeaweedIdentityAccessManagement_GetConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetConfigurationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).GetConfiguration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_GetConfiguration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).GetConfiguration(ctx, req.(*GetConfigurationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_PutConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PutConfigurationRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).PutConfiguration(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_PutConfiguration_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).PutConfiguration(ctx, req.(*PutConfigurationRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).CreateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_CreateUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).CreateUser(ctx, req.(*CreateUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).GetUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_GetUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).GetUser(ctx, req.(*GetUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).UpdateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_UpdateUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).UpdateUser(ctx, req.(*UpdateUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).DeleteUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_DeleteUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).DeleteUser(ctx, req.(*DeleteUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_ListUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListUsersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).ListUsers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_ListUsers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).ListUsers(ctx, req.(*ListUsersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_CreateAccessKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateAccessKeyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).CreateAccessKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_CreateAccessKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).CreateAccessKey(ctx, req.(*CreateAccessKeyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_DeleteAccessKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteAccessKeyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).DeleteAccessKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_DeleteAccessKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).DeleteAccessKey(ctx, req.(*DeleteAccessKeyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedIdentityAccessManagement_GetUserByAccessKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserByAccessKeyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedIdentityAccessManagementServer).GetUserByAccessKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedIdentityAccessManagement_GetUserByAccessKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedIdentityAccessManagementServer).GetUserByAccessKey(ctx, req.(*GetUserByAccessKeyRequest))
}
return interceptor(ctx, in, info, handler)
}
// SeaweedIdentityAccessManagement_ServiceDesc is the grpc.ServiceDesc for SeaweedIdentityAccessManagement service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var SeaweedIdentityAccessManagement_ServiceDesc = grpc.ServiceDesc{
ServiceName: "iam_pb.SeaweedIdentityAccessManagement",
HandlerType: (*SeaweedIdentityAccessManagementServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{},
Metadata: "iam.proto",
Methods: []grpc.MethodDesc{
{
MethodName: "GetConfiguration",
Handler: _SeaweedIdentityAccessManagement_GetConfiguration_Handler,
},
{
MethodName: "PutConfiguration",
Handler: _SeaweedIdentityAccessManagement_PutConfiguration_Handler,
},
{
MethodName: "CreateUser",
Handler: _SeaweedIdentityAccessManagement_CreateUser_Handler,
},
{
MethodName: "GetUser",
Handler: _SeaweedIdentityAccessManagement_GetUser_Handler,
},
{
MethodName: "UpdateUser",
Handler: _SeaweedIdentityAccessManagement_UpdateUser_Handler,
},
{
MethodName: "DeleteUser",
Handler: _SeaweedIdentityAccessManagement_DeleteUser_Handler,
},
{
MethodName: "ListUsers",
Handler: _SeaweedIdentityAccessManagement_ListUsers_Handler,
},
{
MethodName: "CreateAccessKey",
Handler: _SeaweedIdentityAccessManagement_CreateAccessKey_Handler,
},
{
MethodName: "DeleteAccessKey",
Handler: _SeaweedIdentityAccessManagement_DeleteAccessKey_Handler,
},
{
MethodName: "GetUserByAccessKey",
Handler: _SeaweedIdentityAccessManagement_GetUserByAccessKey_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "iam.proto",
}
+6
View File
@@ -10,6 +10,7 @@ import (
"sync/atomic"
"time"
"github.com/seaweedfs/seaweedfs/weed/credential"
"github.com/seaweedfs/seaweedfs/weed/stats"
"golang.org/x/sync/singleflight"
@@ -81,6 +82,7 @@ type FilerOption struct {
AllowedOrigins []string
ExposeDirectoryData bool
TusBasePath string
CredentialManager *credential.CredentialManager
}
type FilerServer struct {
@@ -112,6 +114,9 @@ type FilerServer struct {
// deduplicates concurrent remote object caching operations
remoteCacheGroup singleflight.Group
// credential manager for IAM operations
credentialManager *credential.CredentialManager
}
func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) (fs *FilerServer, err error) {
@@ -148,6 +153,7 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption)
grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.filer"),
knownListeners: make(map[int32]int32),
inFlightDataLimitCond: sync.NewCond(new(sync.Mutex)),
credentialManager: option.CredentialManager,
}
fs.listenersCond = sync.NewCond(&fs.listenersLock)
@@ -0,0 +1,203 @@
package weed_server
import (
"context"
"github.com/seaweedfs/seaweedfs/weed/credential"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
)
// IamGrpcServer implements the IAM gRPC service on the filer
type IamGrpcServer struct {
iam_pb.UnimplementedSeaweedIdentityAccessManagementServer
credentialManager *credential.CredentialManager
}
// NewIamGrpcServer creates a new IAM gRPC server
func NewIamGrpcServer(credentialManager *credential.CredentialManager) *IamGrpcServer {
return &IamGrpcServer{
credentialManager: credentialManager,
}
}
//////////////////////////////////////////////////
// Configuration Management
func (s *IamGrpcServer) GetConfiguration(ctx context.Context, req *iam_pb.GetConfigurationRequest) (*iam_pb.GetConfigurationResponse, error) {
glog.V(4).Infof("GetConfiguration")
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
config, err := s.credentialManager.LoadConfiguration(ctx)
if err != nil {
glog.Errorf("Failed to load configuration: %v", err)
return nil, err
}
return &iam_pb.GetConfigurationResponse{
Configuration: config,
}, nil
}
func (s *IamGrpcServer) PutConfiguration(ctx context.Context, req *iam_pb.PutConfigurationRequest) (*iam_pb.PutConfigurationResponse, error) {
glog.V(4).Infof("PutConfiguration")
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
if req.Configuration == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.SaveConfiguration(ctx, req.Configuration)
if err != nil {
glog.Errorf("Failed to save configuration: %v", err)
return nil, err
}
return &iam_pb.PutConfigurationResponse{}, nil
}
//////////////////////////////////////////////////
// User Management
func (s *IamGrpcServer) CreateUser(ctx context.Context, req *iam_pb.CreateUserRequest) (*iam_pb.CreateUserResponse, error) {
glog.V(4).Infof("CreateUser: %s", req.Identity.Name)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.CreateUser(ctx, req.Identity)
if err != nil {
glog.Errorf("Failed to create user %s: %v", req.Identity.Name, err)
return nil, err
}
return &iam_pb.CreateUserResponse{}, nil
}
func (s *IamGrpcServer) GetUser(ctx context.Context, req *iam_pb.GetUserRequest) (*iam_pb.GetUserResponse, error) {
glog.V(4).Infof("GetUser: %s", req.Username)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
identity, err := s.credentialManager.GetUser(ctx, req.Username)
if err != nil {
glog.Errorf("Failed to get user %s: %v", req.Username, err)
return nil, err
}
return &iam_pb.GetUserResponse{
Identity: identity,
}, nil
}
func (s *IamGrpcServer) UpdateUser(ctx context.Context, req *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error) {
glog.V(4).Infof("UpdateUser: %s", req.Username)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.UpdateUser(ctx, req.Username, req.Identity)
if err != nil {
glog.Errorf("Failed to update user %s: %v", req.Username, err)
return nil, err
}
return &iam_pb.UpdateUserResponse{}, nil
}
func (s *IamGrpcServer) DeleteUser(ctx context.Context, req *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error) {
glog.V(4).Infof("DeleteUser: %s", req.Username)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.DeleteUser(ctx, req.Username)
if err != nil {
glog.Errorf("Failed to delete user %s: %v", req.Username, err)
return nil, err
}
return &iam_pb.DeleteUserResponse{}, nil
}
func (s *IamGrpcServer) ListUsers(ctx context.Context, req *iam_pb.ListUsersRequest) (*iam_pb.ListUsersResponse, error) {
glog.V(4).Infof("ListUsers")
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
usernames, err := s.credentialManager.ListUsers(ctx)
if err != nil {
glog.Errorf("Failed to list users: %v", err)
return nil, err
}
return &iam_pb.ListUsersResponse{
Usernames: usernames,
}, nil
}
//////////////////////////////////////////////////
// Access Key Management
func (s *IamGrpcServer) CreateAccessKey(ctx context.Context, req *iam_pb.CreateAccessKeyRequest) (*iam_pb.CreateAccessKeyResponse, error) {
glog.V(4).Infof("CreateAccessKey for user: %s", req.Username)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.CreateAccessKey(ctx, req.Username, req.Credential)
if err != nil {
glog.Errorf("Failed to create access key for user %s: %v", req.Username, err)
return nil, err
}
return &iam_pb.CreateAccessKeyResponse{}, nil
}
func (s *IamGrpcServer) DeleteAccessKey(ctx context.Context, req *iam_pb.DeleteAccessKeyRequest) (*iam_pb.DeleteAccessKeyResponse, error) {
glog.V(4).Infof("DeleteAccessKey: %s for user: %s", req.AccessKey, req.Username)
if s.credentialManager == nil {
return nil, credential.ErrUserNotFound
}
err := s.credentialManager.DeleteAccessKey(ctx, req.Username, req.AccessKey)
if err != nil {
glog.Errorf("Failed to delete access key %s for user %s: %v", req.AccessKey, req.Username, err)
return nil, err
}
return &iam_pb.DeleteAccessKeyResponse{}, nil
}
func (s *IamGrpcServer) GetUserByAccessKey(ctx context.Context, req *iam_pb.GetUserByAccessKeyRequest) (*iam_pb.GetUserByAccessKeyResponse, error) {
glog.V(4).Infof("GetUserByAccessKey: %s", req.AccessKey)
if s.credentialManager == nil {
return nil, credential.ErrAccessKeyNotFound
}
identity, err := s.credentialManager.GetUserByAccessKey(ctx, req.AccessKey)
if err != nil {
glog.Errorf("Failed to get user by access key %s: %v", req.AccessKey, err)
return nil, err
}
return &iam_pb.GetUserByAccessKeyResponse{
Identity: identity,
}, nil
}