Browse Source

address comments

pull/7160/head
chrislu 1 month ago
parent
commit
0575d93bca
  1. 16
      .github/workflows/s3-iam-tests.yml
  2. 18
      weed/iam/integration/iam_manager.go
  3. 84
      weed/iam/integration/role_store.go
  4. 28
      weed/iam/policy/policy_engine.go
  5. 75
      weed/iam/policy/policy_store.go
  6. 4
      weed/s3api/s3api_server.go

16
.github/workflows/s3-iam-tests.yml

@ -165,6 +165,14 @@ jobs:
chmod +x setup_keycloak.sh
./setup_keycloak.sh
# Wait for the test realm to be fully available
echo "Waiting for seaweedfs-test realm to be available..."
timeout 120 bash -c 'until curl -fs http://localhost:8080/realms/seaweedfs-test/.well-known/openid-configuration > /dev/null; do echo "... waiting for realm"; sleep 3; done' || {
echo "❌ seaweedfs-test realm not available"
docker logs keycloak --tail=200 || true
exit 1
}
# Start SeaweedFS services
make clean setup start-services wait-for-services
@ -300,6 +308,14 @@ jobs:
# Give services extra time to fully initialize
sleep 10
# Ensure the seaweedfs-test realm is available before running tests
echo "Waiting for seaweedfs-test realm to be available..."
timeout 120 bash -c 'until curl -fs http://localhost:8080/realms/seaweedfs-test/.well-known/openid-configuration > /dev/null; do echo "... waiting for realm"; sleep 3; done' || {
echo "❌ seaweedfs-test realm not available"
docker logs keycloak --tail=200 || true
exit 1
}
# Verify services are accessible
echo "=== Verifying Service Accessibility ==="
curl -f http://localhost:8080/realms/master || {

18
weed/iam/integration/iam_manager.go

@ -139,16 +139,16 @@ func (m *IAMManager) RegisterIdentityProvider(provider providers.IdentityProvide
}
// CreatePolicy creates a new policy
func (m *IAMManager) CreatePolicy(ctx context.Context, name string, policyDoc *policy.PolicyDocument) error {
func (m *IAMManager) CreatePolicy(ctx context.Context, filerAddress string, name string, policyDoc *policy.PolicyDocument) error {
if !m.initialized {
return fmt.Errorf("IAM manager not initialized")
}
return m.policyEngine.AddPolicy(name, policyDoc)
return m.policyEngine.AddPolicy(filerAddress, name, policyDoc)
}
// CreateRole creates a new role with trust policy and attached policies
func (m *IAMManager) CreateRole(ctx context.Context, roleName string, roleDef *RoleDefinition) error {
func (m *IAMManager) CreateRole(ctx context.Context, filerAddress string, roleName string, roleDef *RoleDefinition) error {
if !m.initialized {
return fmt.Errorf("IAM manager not initialized")
}
@ -174,7 +174,7 @@ func (m *IAMManager) CreateRole(ctx context.Context, roleName string, roleDef *R
}
// Store role definition
return m.roleStore.StoreRole(ctx, roleName, roleDef)
return m.roleStore.StoreRole(ctx, "", roleName, roleDef)
}
// AssumeRoleWithWebIdentity assumes a role using web identity (OIDC)
@ -187,7 +187,7 @@ func (m *IAMManager) AssumeRoleWithWebIdentity(ctx context.Context, request *sts
roleName := extractRoleNameFromArn(request.RoleArn)
// Get role definition
roleDef, err := m.roleStore.GetRole(ctx, roleName)
roleDef, err := m.roleStore.GetRole(ctx, "", roleName)
if err != nil {
return nil, fmt.Errorf("role not found: %s", roleName)
}
@ -211,7 +211,7 @@ func (m *IAMManager) AssumeRoleWithCredentials(ctx context.Context, request *sts
roleName := extractRoleNameFromArn(request.RoleArn)
// Get role definition
roleDef, err := m.roleStore.GetRole(ctx, roleName)
roleDef, err := m.roleStore.GetRole(ctx, "", roleName)
if err != nil {
return nil, fmt.Errorf("role not found: %s", roleName)
}
@ -246,7 +246,7 @@ func (m *IAMManager) IsActionAllowed(ctx context.Context, request *ActionRequest
}
// Get role definition
roleDef, err := m.roleStore.GetRole(ctx, roleName)
roleDef, err := m.roleStore.GetRole(ctx, "", roleName)
if err != nil {
return false, fmt.Errorf("role not found: %s", roleName)
}
@ -260,7 +260,7 @@ func (m *IAMManager) IsActionAllowed(ctx context.Context, request *ActionRequest
}
// Evaluate policies attached to the role
result, err := m.policyEngine.Evaluate(ctx, evalCtx, roleDef.AttachedPolicies)
result, err := m.policyEngine.Evaluate(ctx, "", evalCtx, roleDef.AttachedPolicies)
if err != nil {
return false, fmt.Errorf("policy evaluation failed: %w", err)
}
@ -271,7 +271,7 @@ func (m *IAMManager) IsActionAllowed(ctx context.Context, request *ActionRequest
// ValidateTrustPolicy validates if a principal can assume a role (for testing)
func (m *IAMManager) ValidateTrustPolicy(ctx context.Context, roleArn, provider, userID string) bool {
roleName := extractRoleNameFromArn(roleArn)
roleDef, err := m.roleStore.GetRole(ctx, roleName)
roleDef, err := m.roleStore.GetRole(ctx, "", roleName)
if err != nil {
return false
}

84
weed/iam/integration/role_store.go

@ -17,17 +17,17 @@ import (
// RoleStore defines the interface for storing IAM role definitions
type RoleStore interface {
// StoreRole stores a role definition
StoreRole(ctx context.Context, roleName string, role *RoleDefinition) error
// StoreRole stores a role definition (filerAddress ignored for memory stores)
StoreRole(ctx context.Context, filerAddress string, roleName string, role *RoleDefinition) error
// GetRole retrieves a role definition
GetRole(ctx context.Context, roleName string) (*RoleDefinition, error)
// GetRole retrieves a role definition (filerAddress ignored for memory stores)
GetRole(ctx context.Context, filerAddress string, roleName string) (*RoleDefinition, error)
// ListRoles lists all role names
ListRoles(ctx context.Context) ([]string, error)
// ListRoles lists all role names (filerAddress ignored for memory stores)
ListRoles(ctx context.Context, filerAddress string) ([]string, error)
// DeleteRole deletes a role definition
DeleteRole(ctx context.Context, roleName string) error
// DeleteRole deletes a role definition (filerAddress ignored for memory stores)
DeleteRole(ctx context.Context, filerAddress string, roleName string) error
}
// MemoryRoleStore implements RoleStore using in-memory storage
@ -43,8 +43,8 @@ func NewMemoryRoleStore() *MemoryRoleStore {
}
}
// StoreRole stores a role definition in memory
func (m *MemoryRoleStore) StoreRole(ctx context.Context, roleName string, role *RoleDefinition) error {
// StoreRole stores a role definition in memory (filerAddress ignored for memory store)
func (m *MemoryRoleStore) StoreRole(ctx context.Context, filerAddress string, roleName string, role *RoleDefinition) error {
if roleName == "" {
return fmt.Errorf("role name cannot be empty")
}
@ -60,8 +60,8 @@ func (m *MemoryRoleStore) StoreRole(ctx context.Context, roleName string, role *
return nil
}
// GetRole retrieves a role definition from memory
func (m *MemoryRoleStore) GetRole(ctx context.Context, roleName string) (*RoleDefinition, error) {
// GetRole retrieves a role definition from memory (filerAddress ignored for memory store)
func (m *MemoryRoleStore) GetRole(ctx context.Context, filerAddress string, roleName string) (*RoleDefinition, error) {
if roleName == "" {
return nil, fmt.Errorf("role name cannot be empty")
}
@ -78,8 +78,8 @@ func (m *MemoryRoleStore) GetRole(ctx context.Context, roleName string) (*RoleDe
return copyRoleDefinition(role), nil
}
// ListRoles lists all role names in memory
func (m *MemoryRoleStore) ListRoles(ctx context.Context) ([]string, error) {
// ListRoles lists all role names in memory (filerAddress ignored for memory store)
func (m *MemoryRoleStore) ListRoles(ctx context.Context, filerAddress string) ([]string, error) {
m.mutex.RLock()
defer m.mutex.RUnlock()
@ -91,8 +91,8 @@ func (m *MemoryRoleStore) ListRoles(ctx context.Context) ([]string, error) {
return names, nil
}
// DeleteRole deletes a role definition from memory
func (m *MemoryRoleStore) DeleteRole(ctx context.Context, roleName string) error {
// DeleteRole deletes a role definition from memory (filerAddress ignored for memory store)
func (m *MemoryRoleStore) DeleteRole(ctx context.Context, filerAddress string, roleName string) error {
if roleName == "" {
return fmt.Errorf("role name cannot be empty")
}
@ -136,7 +136,6 @@ func copyRoleDefinition(original *RoleDefinition) *RoleDefinition {
// FilerRoleStore implements RoleStore using SeaweedFS filer
type FilerRoleStore struct {
filerGrpcAddress string
grpcDialOption grpc.DialOption
basePath string
}
@ -147,29 +146,23 @@ func NewFilerRoleStore(config map[string]interface{}) (*FilerRoleStore, error) {
basePath: "/etc/iam/roles", // Default path for role storage - aligned with /etc/ convention
}
// Parse configuration
// Parse configuration - only basePath and other settings, NOT filerAddress
if config != nil {
if filerAddr, ok := config["filerAddress"].(string); ok {
store.filerGrpcAddress = filerAddr
}
if basePath, ok := config["basePath"].(string); ok {
if basePath, ok := config["basePath"].(string); ok && basePath != "" {
store.basePath = strings.TrimSuffix(basePath, "/")
}
}
// Validate configuration
if store.filerGrpcAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerRoleStore")
}
glog.V(2).Infof("Initialized FilerRoleStore with filer %s, basePath %s",
store.filerGrpcAddress, store.basePath)
glog.V(2).Infof("Initialized FilerRoleStore with basePath %s", store.basePath)
return store, nil
}
// StoreRole stores a role definition in filer
func (f *FilerRoleStore) StoreRole(ctx context.Context, roleName string, role *RoleDefinition) error {
func (f *FilerRoleStore) StoreRole(ctx context.Context, filerAddress string, roleName string, role *RoleDefinition) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerRoleStore")
}
if roleName == "" {
return fmt.Errorf("role name cannot be empty")
}
@ -186,7 +179,7 @@ func (f *FilerRoleStore) StoreRole(ctx context.Context, roleName string, role *R
rolePath := f.getRolePath(roleName)
// Store in filer
return f.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
return f.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.CreateEntryRequest{
Directory: f.basePath,
Entry: &filer_pb.Entry{
@ -214,13 +207,16 @@ func (f *FilerRoleStore) StoreRole(ctx context.Context, roleName string, role *R
}
// GetRole retrieves a role definition from filer
func (f *FilerRoleStore) GetRole(ctx context.Context, roleName string) (*RoleDefinition, error) {
func (f *FilerRoleStore) GetRole(ctx context.Context, filerAddress string, roleName string) (*RoleDefinition, error) {
if filerAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerRoleStore")
}
if roleName == "" {
return nil, fmt.Errorf("role name cannot be empty")
}
var roleData []byte
err := f.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
err := f.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.LookupDirectoryEntryRequest{
Directory: f.basePath,
Name: f.getRoleFileName(roleName),
@ -254,10 +250,14 @@ func (f *FilerRoleStore) GetRole(ctx context.Context, roleName string) (*RoleDef
}
// ListRoles lists all role names in filer
func (f *FilerRoleStore) ListRoles(ctx context.Context) ([]string, error) {
func (f *FilerRoleStore) ListRoles(ctx context.Context, filerAddress string) ([]string, error) {
if filerAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerRoleStore")
}
var roleNames []string
err := f.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
err := f.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.ListEntriesRequest{
Directory: f.basePath,
Prefix: "",
@ -301,12 +301,15 @@ func (f *FilerRoleStore) ListRoles(ctx context.Context) ([]string, error) {
}
// DeleteRole deletes a role definition from filer
func (f *FilerRoleStore) DeleteRole(ctx context.Context, roleName string) error {
func (f *FilerRoleStore) DeleteRole(ctx context.Context, filerAddress string, roleName string) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerRoleStore")
}
if roleName == "" {
return fmt.Errorf("role name cannot be empty")
}
return f.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
return f.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.DeleteEntryRequest{
Directory: f.basePath,
Name: f.getRoleFileName(roleName),
@ -333,6 +336,9 @@ func (f *FilerRoleStore) getRolePath(roleName string) string {
return f.basePath + "/" + f.getRoleFileName(roleName)
}
func (f *FilerRoleStore) withFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error {
return pb.WithGrpcFilerClient(false, 0, pb.ServerAddress(f.filerGrpcAddress), f.grpcDialOption, fn)
func (f *FilerRoleStore) withFilerClient(filerAddress string, fn func(filer_pb.SeaweedFilerClient) error) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerRoleStore")
}
return pb.WithGrpcFilerClient(false, 0, pb.ServerAddress(filerAddress), f.grpcDialOption, fn)
}

28
weed/iam/policy/policy_engine.go

@ -139,17 +139,17 @@ type EvaluationDetails struct {
// PolicyStore defines the interface for storing and retrieving policies
type PolicyStore interface {
// StorePolicy stores a policy document
StorePolicy(ctx context.Context, name string, policy *PolicyDocument) error
// StorePolicy stores a policy document (filerAddress ignored for memory stores)
StorePolicy(ctx context.Context, filerAddress string, name string, policy *PolicyDocument) error
// GetPolicy retrieves a policy document
GetPolicy(ctx context.Context, name string) (*PolicyDocument, error)
// GetPolicy retrieves a policy document (filerAddress ignored for memory stores)
GetPolicy(ctx context.Context, filerAddress string, name string) (*PolicyDocument, error)
// DeletePolicy deletes a policy document
DeletePolicy(ctx context.Context, name string) error
// DeletePolicy deletes a policy document (filerAddress ignored for memory stores)
DeletePolicy(ctx context.Context, filerAddress string, name string) error
// ListPolicies lists all policy names
ListPolicies(ctx context.Context) ([]string, error)
// ListPolicies lists all policy names (filerAddress ignored for memory stores)
ListPolicies(ctx context.Context, filerAddress string) ([]string, error)
}
// NewPolicyEngine creates a new policy engine
@ -210,8 +210,8 @@ func (e *PolicyEngine) IsInitialized() bool {
return e.initialized
}
// AddPolicy adds a policy to the engine
func (e *PolicyEngine) AddPolicy(name string, policy *PolicyDocument) error {
// AddPolicy adds a policy to the engine (filerAddress ignored for memory stores)
func (e *PolicyEngine) AddPolicy(filerAddress string, name string, policy *PolicyDocument) error {
if !e.initialized {
return fmt.Errorf("policy engine not initialized")
}
@ -228,11 +228,11 @@ func (e *PolicyEngine) AddPolicy(name string, policy *PolicyDocument) error {
return fmt.Errorf("invalid policy document: %w", err)
}
return e.store.StorePolicy(context.Background(), name, policy)
return e.store.StorePolicy(context.Background(), filerAddress, name, policy)
}
// Evaluate evaluates policies against a request context
func (e *PolicyEngine) Evaluate(ctx context.Context, evalCtx *EvaluationContext, policyNames []string) (*EvaluationResult, error) {
// Evaluate evaluates policies against a request context (filerAddress ignored for memory stores)
func (e *PolicyEngine) Evaluate(ctx context.Context, filerAddress string, evalCtx *EvaluationContext, policyNames []string) (*EvaluationResult, error) {
if !e.initialized {
return nil, fmt.Errorf("policy engine not initialized")
}
@ -257,7 +257,7 @@ func (e *PolicyEngine) Evaluate(ctx context.Context, evalCtx *EvaluationContext,
// Evaluate each policy
for _, policyName := range policyNames {
policy, err := e.store.GetPolicy(ctx, policyName)
policy, err := e.store.GetPolicy(ctx, filerAddress, policyName)
if err != nil {
continue // Skip policies that can't be loaded
}

75
weed/iam/policy/policy_store.go

@ -27,8 +27,8 @@ func NewMemoryPolicyStore() *MemoryPolicyStore {
}
}
// StorePolicy stores a policy document in memory
func (s *MemoryPolicyStore) StorePolicy(ctx context.Context, name string, policy *PolicyDocument) error {
// StorePolicy stores a policy document in memory (filerAddress ignored for memory store)
func (s *MemoryPolicyStore) StorePolicy(ctx context.Context, filerAddress string, name string, policy *PolicyDocument) error {
if name == "" {
return fmt.Errorf("policy name cannot be empty")
}
@ -45,8 +45,8 @@ func (s *MemoryPolicyStore) StorePolicy(ctx context.Context, name string, policy
return nil
}
// GetPolicy retrieves a policy document from memory
func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, name string) (*PolicyDocument, error) {
// GetPolicy retrieves a policy document from memory (filerAddress ignored for memory store)
func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, filerAddress string, name string) (*PolicyDocument, error) {
if name == "" {
return nil, fmt.Errorf("policy name cannot be empty")
}
@ -63,8 +63,8 @@ func (s *MemoryPolicyStore) GetPolicy(ctx context.Context, name string) (*Policy
return copyPolicyDocument(policy), nil
}
// DeletePolicy deletes a policy document from memory
func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, name string) error {
// DeletePolicy deletes a policy document from memory (filerAddress ignored for memory store)
func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, filerAddress string, name string) error {
if name == "" {
return fmt.Errorf("policy name cannot be empty")
}
@ -76,8 +76,8 @@ func (s *MemoryPolicyStore) DeletePolicy(ctx context.Context, name string) error
return nil
}
// ListPolicies lists all policy names in memory
func (s *MemoryPolicyStore) ListPolicies(ctx context.Context) ([]string, error) {
// ListPolicies lists all policy names in memory (filerAddress ignored for memory store)
func (s *MemoryPolicyStore) ListPolicies(ctx context.Context, filerAddress string) ([]string, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
@ -148,7 +148,6 @@ func copyPolicyDocument(original *PolicyDocument) *PolicyDocument {
// FilerPolicyStore implements PolicyStore using SeaweedFS filer
type FilerPolicyStore struct {
filerGrpcAddress string
grpcDialOption grpc.DialOption
basePath string
}
@ -159,29 +158,23 @@ func NewFilerPolicyStore(config map[string]interface{}) (*FilerPolicyStore, erro
basePath: "/etc/iam/policies", // Default path for policy storage - aligned with /etc/ convention
}
// Parse configuration
// Parse configuration - only basePath and other settings, NOT filerAddress
if config != nil {
if filerAddr, ok := config["filerAddress"].(string); ok {
store.filerGrpcAddress = filerAddr
}
if basePath, ok := config["basePath"].(string); ok {
if basePath, ok := config["basePath"].(string); ok && basePath != "" {
store.basePath = strings.TrimSuffix(basePath, "/")
}
}
// Validate configuration
if store.filerGrpcAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerPolicyStore")
}
glog.V(2).Infof("Initialized FilerPolicyStore with filer %s, basePath %s",
store.filerGrpcAddress, store.basePath)
glog.V(2).Infof("Initialized FilerPolicyStore with basePath %s", store.basePath)
return store, nil
}
// StorePolicy stores a policy document in filer
func (s *FilerPolicyStore) StorePolicy(ctx context.Context, name string, policy *PolicyDocument) error {
func (s *FilerPolicyStore) StorePolicy(ctx context.Context, filerAddress string, name string, policy *PolicyDocument) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerPolicyStore")
}
if name == "" {
return fmt.Errorf("policy name cannot be empty")
}
@ -198,7 +191,7 @@ func (s *FilerPolicyStore) StorePolicy(ctx context.Context, name string, policy
policyPath := s.getPolicyPath(name)
// Store in filer
return s.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
return s.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.CreateEntryRequest{
Directory: s.basePath,
Entry: &filer_pb.Entry{
@ -226,13 +219,16 @@ func (s *FilerPolicyStore) StorePolicy(ctx context.Context, name string, policy
}
// GetPolicy retrieves a policy document from filer
func (s *FilerPolicyStore) GetPolicy(ctx context.Context, name string) (*PolicyDocument, error) {
func (s *FilerPolicyStore) GetPolicy(ctx context.Context, filerAddress string, name string) (*PolicyDocument, error) {
if filerAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerPolicyStore")
}
if name == "" {
return nil, fmt.Errorf("policy name cannot be empty")
}
var policyData []byte
err := s.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
err := s.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.LookupDirectoryEntryRequest{
Directory: s.basePath,
Name: s.getPolicyFileName(name),
@ -266,12 +262,15 @@ func (s *FilerPolicyStore) GetPolicy(ctx context.Context, name string) (*PolicyD
}
// DeletePolicy deletes a policy document from filer
func (s *FilerPolicyStore) DeletePolicy(ctx context.Context, name string) error {
func (s *FilerPolicyStore) DeletePolicy(ctx context.Context, filerAddress string, name string) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerPolicyStore")
}
if name == "" {
return fmt.Errorf("policy name cannot be empty")
}
return s.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
return s.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.DeleteEntryRequest{
Directory: s.basePath,
Name: s.getPolicyFileName(name),
@ -304,10 +303,14 @@ func (s *FilerPolicyStore) DeletePolicy(ctx context.Context, name string) error
}
// ListPolicies lists all policy names in filer
func (s *FilerPolicyStore) ListPolicies(ctx context.Context) ([]string, error) {
func (s *FilerPolicyStore) ListPolicies(ctx context.Context, filerAddress string) ([]string, error) {
if filerAddress == "" {
return nil, fmt.Errorf("filer address is required for FilerPolicyStore")
}
var policyNames []string
err := s.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
err := s.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
// List all entries in the policy directory
request := &filer_pb.ListEntriesRequest{
Directory: s.basePath,
@ -353,20 +356,14 @@ func (s *FilerPolicyStore) ListPolicies(ctx context.Context) ([]string, error) {
// Helper methods
// SetFilerClient sets the filer client connection details
func (s *FilerPolicyStore) SetFilerClient(filerAddress string, grpcDialOption grpc.DialOption) {
s.filerGrpcAddress = filerAddress
s.grpcDialOption = grpcDialOption
}
// withFilerClient executes a function with a filer client
func (s *FilerPolicyStore) withFilerClient(fn func(client filer_pb.SeaweedFilerClient) error) error {
if s.filerGrpcAddress == "" {
return fmt.Errorf("filer address not configured")
func (s *FilerPolicyStore) withFilerClient(filerAddress string, fn func(client filer_pb.SeaweedFilerClient) error) error {
if filerAddress == "" {
return fmt.Errorf("filer address is required for FilerPolicyStore")
}
// Use the pb.WithGrpcFilerClient helper similar to existing SeaweedFS code
return pb.WithGrpcFilerClient(false, 0, pb.ServerAddress(s.filerGrpcAddress), s.grpcDialOption, fn)
return pb.WithGrpcFilerClient(false, 0, pb.ServerAddress(filerAddress), s.grpcDialOption, fn)
}
// getPolicyPath returns the full path for a policy

4
weed/s3api/s3api_server.go

@ -474,14 +474,14 @@ func loadIAMManagerFromConfig(configPath string) (*integration.IAMManager, error
// Load policies
for _, policyDef := range configRoot.Policies {
if err := iamManager.CreatePolicy(context.Background(), policyDef.Name, policyDef.Document); err != nil {
if err := iamManager.CreatePolicy(context.Background(), "", policyDef.Name, policyDef.Document); err != nil {
glog.Warningf("Failed to create policy %s: %v", policyDef.Name, err)
}
}
// Load roles
for _, roleDef := range configRoot.Roles {
if err := iamManager.CreateRole(context.Background(), roleDef.RoleName, roleDef); err != nil {
if err := iamManager.CreateRole(context.Background(), "", roleDef.RoleName, roleDef); err != nil {
glog.Warningf("Failed to create role %s: %v", roleDef.RoleName, err)
}
}

Loading…
Cancel
Save