You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							153 lines
						
					
					
						
							4.7 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							153 lines
						
					
					
						
							4.7 KiB
						
					
					
				| package integration | |
| 
 | |
| import ( | |
| 	"context" | |
| 	"encoding/json" | |
| 	"time" | |
| 
 | |
| 	"github.com/seaweedfs/seaweedfs/weed/glog" | |
| 	"github.com/seaweedfs/seaweedfs/weed/iam/policy" | |
| 	"github.com/seaweedfs/seaweedfs/weed/iam/util" | |
| ) | |
| 
 | |
| // RoleStoreAdapter adapts RoleStore interface to CacheableStore[*RoleDefinition] | |
| type RoleStoreAdapter struct { | |
| 	store RoleStore | |
| } | |
| 
 | |
| // NewRoleStoreAdapter creates a new adapter for RoleStore | |
| func NewRoleStoreAdapter(store RoleStore) *RoleStoreAdapter { | |
| 	return &RoleStoreAdapter{store: store} | |
| } | |
| 
 | |
| // Get implements CacheableStore interface | |
| func (a *RoleStoreAdapter) Get(ctx context.Context, filerAddress string, key string) (*RoleDefinition, error) { | |
| 	return a.store.GetRole(ctx, filerAddress, key) | |
| } | |
| 
 | |
| // Store implements CacheableStore interface | |
| func (a *RoleStoreAdapter) Store(ctx context.Context, filerAddress string, key string, value *RoleDefinition) error { | |
| 	return a.store.StoreRole(ctx, filerAddress, key, value) | |
| } | |
| 
 | |
| // Delete implements CacheableStore interface | |
| func (a *RoleStoreAdapter) Delete(ctx context.Context, filerAddress string, key string) error { | |
| 	return a.store.DeleteRole(ctx, filerAddress, key) | |
| } | |
| 
 | |
| // List implements CacheableStore interface | |
| func (a *RoleStoreAdapter) List(ctx context.Context, filerAddress string) ([]string, error) { | |
| 	return a.store.ListRoles(ctx, filerAddress) | |
| } | |
| 
 | |
| // GenericCachedRoleStore implements RoleStore using the generic cache | |
| type GenericCachedRoleStore struct { | |
| 	*util.CachedStore[*RoleDefinition] | |
| 	adapter *RoleStoreAdapter | |
| } | |
| 
 | |
| // NewGenericCachedRoleStore creates a new cached role store using generics | |
| func NewGenericCachedRoleStore(config map[string]interface{}, filerAddressProvider func() string) (*GenericCachedRoleStore, error) { | |
| 	// Create underlying filer store | |
| 	filerStore, err := NewFilerRoleStore(config, filerAddressProvider) | |
| 	if err != nil { | |
| 		return nil, err | |
| 	} | |
| 
 | |
| 	// Parse cache configuration with defaults | |
| 	cacheTTL := 5 * time.Minute | |
| 	listTTL := 1 * time.Minute | |
| 	maxCacheSize := int64(1000) | |
| 
 | |
| 	if config != nil { | |
| 		if ttlStr, ok := config["ttl"].(string); ok && ttlStr != "" { | |
| 			if parsed, err := time.ParseDuration(ttlStr); err == nil { | |
| 				cacheTTL = parsed | |
| 			} | |
| 		} | |
| 		if listTTLStr, ok := config["listTtl"].(string); ok && listTTLStr != "" { | |
| 			if parsed, err := time.ParseDuration(listTTLStr); err == nil { | |
| 				listTTL = parsed | |
| 			} | |
| 		} | |
| 		if maxSize, ok := config["maxCacheSize"].(int); ok && maxSize > 0 { | |
| 			maxCacheSize = int64(maxSize) | |
| 		} | |
| 	} | |
| 
 | |
| 	// Create adapter and generic cached store | |
| 	adapter := NewRoleStoreAdapter(filerStore) | |
| 	cachedStore := util.NewCachedStore( | |
| 		adapter, | |
| 		genericCopyRoleDefinition, // Copy function | |
| 		util.CachedStoreConfig{ | |
| 			TTL:          cacheTTL, | |
| 			ListTTL:      listTTL, | |
| 			MaxCacheSize: maxCacheSize, | |
| 		}, | |
| 	) | |
| 
 | |
| 	glog.V(2).Infof("Initialized GenericCachedRoleStore with TTL %v, List TTL %v, Max Cache Size %d", | |
| 		cacheTTL, listTTL, maxCacheSize) | |
| 
 | |
| 	return &GenericCachedRoleStore{ | |
| 		CachedStore: cachedStore, | |
| 		adapter:     adapter, | |
| 	}, nil | |
| } | |
| 
 | |
| // StoreRole implements RoleStore interface | |
| func (c *GenericCachedRoleStore) StoreRole(ctx context.Context, filerAddress string, roleName string, role *RoleDefinition) error { | |
| 	return c.Store(ctx, filerAddress, roleName, role) | |
| } | |
| 
 | |
| // GetRole implements RoleStore interface | |
| func (c *GenericCachedRoleStore) GetRole(ctx context.Context, filerAddress string, roleName string) (*RoleDefinition, error) { | |
| 	return c.Get(ctx, filerAddress, roleName) | |
| } | |
| 
 | |
| // ListRoles implements RoleStore interface | |
| func (c *GenericCachedRoleStore) ListRoles(ctx context.Context, filerAddress string) ([]string, error) { | |
| 	return c.List(ctx, filerAddress) | |
| } | |
| 
 | |
| // DeleteRole implements RoleStore interface | |
| func (c *GenericCachedRoleStore) DeleteRole(ctx context.Context, filerAddress string, roleName string) error { | |
| 	return c.Delete(ctx, filerAddress, roleName) | |
| } | |
| 
 | |
| // genericCopyRoleDefinition creates a deep copy of a RoleDefinition for the generic cache | |
| func genericCopyRoleDefinition(role *RoleDefinition) *RoleDefinition { | |
| 	if role == nil { | |
| 		return nil | |
| 	} | |
| 
 | |
| 	result := &RoleDefinition{ | |
| 		RoleName:    role.RoleName, | |
| 		RoleArn:     role.RoleArn, | |
| 		Description: role.Description, | |
| 	} | |
| 
 | |
| 	// Deep copy trust policy if it exists | |
| 	if role.TrustPolicy != nil { | |
| 		trustPolicyData, err := json.Marshal(role.TrustPolicy) | |
| 		if err != nil { | |
| 			glog.Errorf("Failed to marshal trust policy for deep copy: %v", err) | |
| 			return nil | |
| 		} | |
| 		var trustPolicyCopy policy.PolicyDocument | |
| 		if err := json.Unmarshal(trustPolicyData, &trustPolicyCopy); err != nil { | |
| 			glog.Errorf("Failed to unmarshal trust policy for deep copy: %v", err) | |
| 			return nil | |
| 		} | |
| 		result.TrustPolicy = &trustPolicyCopy | |
| 	} | |
| 
 | |
| 	// Deep copy attached policies slice | |
| 	if role.AttachedPolicies != nil { | |
| 		result.AttachedPolicies = make([]string, len(role.AttachedPolicies)) | |
| 		copy(result.AttachedPolicies, role.AttachedPolicies) | |
| 	} | |
| 
 | |
| 	return result | |
| }
 |