mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-19 13:46:58 +00:00
address comments
This commit is contained in:
@@ -164,6 +164,14 @@ jobs:
|
||||
sudo apt-get install -y jq
|
||||
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
|
||||
@@ -299,6 +307,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 ==="
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,9 +136,8 @@ func copyRoleDefinition(original *RoleDefinition) *RoleDefinition {
|
||||
|
||||
// FilerRoleStore implements RoleStore using SeaweedFS filer
|
||||
type FilerRoleStore struct {
|
||||
filerGrpcAddress string
|
||||
grpcDialOption grpc.DialOption
|
||||
basePath string
|
||||
grpcDialOption grpc.DialOption
|
||||
basePath string
|
||||
}
|
||||
|
||||
// NewFilerRoleStore creates a new filer-based role store
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,9 +148,8 @@ func copyPolicyDocument(original *PolicyDocument) *PolicyDocument {
|
||||
|
||||
// FilerPolicyStore implements PolicyStore using SeaweedFS filer
|
||||
type FilerPolicyStore struct {
|
||||
filerGrpcAddress string
|
||||
grpcDialOption grpc.DialOption
|
||||
basePath string
|
||||
grpcDialOption grpc.DialOption
|
||||
basePath string
|
||||
}
|
||||
|
||||
// NewFilerPolicyStore creates a new filer-based policy store
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user