cached_role_store_generic.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package integration
  2. import (
  3. "context"
  4. "encoding/json"
  5. "time"
  6. "github.com/seaweedfs/seaweedfs/weed/glog"
  7. "github.com/seaweedfs/seaweedfs/weed/iam/policy"
  8. "github.com/seaweedfs/seaweedfs/weed/iam/util"
  9. )
  10. // RoleStoreAdapter adapts RoleStore interface to CacheableStore[*RoleDefinition]
  11. type RoleStoreAdapter struct {
  12. store RoleStore
  13. }
  14. // NewRoleStoreAdapter creates a new adapter for RoleStore
  15. func NewRoleStoreAdapter(store RoleStore) *RoleStoreAdapter {
  16. return &RoleStoreAdapter{store: store}
  17. }
  18. // Get implements CacheableStore interface
  19. func (a *RoleStoreAdapter) Get(ctx context.Context, filerAddress string, key string) (*RoleDefinition, error) {
  20. return a.store.GetRole(ctx, filerAddress, key)
  21. }
  22. // Store implements CacheableStore interface
  23. func (a *RoleStoreAdapter) Store(ctx context.Context, filerAddress string, key string, value *RoleDefinition) error {
  24. return a.store.StoreRole(ctx, filerAddress, key, value)
  25. }
  26. // Delete implements CacheableStore interface
  27. func (a *RoleStoreAdapter) Delete(ctx context.Context, filerAddress string, key string) error {
  28. return a.store.DeleteRole(ctx, filerAddress, key)
  29. }
  30. // List implements CacheableStore interface
  31. func (a *RoleStoreAdapter) List(ctx context.Context, filerAddress string) ([]string, error) {
  32. return a.store.ListRoles(ctx, filerAddress)
  33. }
  34. // GenericCachedRoleStore implements RoleStore using the generic cache
  35. type GenericCachedRoleStore struct {
  36. *util.CachedStore[*RoleDefinition]
  37. adapter *RoleStoreAdapter
  38. }
  39. // NewGenericCachedRoleStore creates a new cached role store using generics
  40. func NewGenericCachedRoleStore(config map[string]interface{}, filerAddressProvider func() string) (*GenericCachedRoleStore, error) {
  41. // Create underlying filer store
  42. filerStore, err := NewFilerRoleStore(config, filerAddressProvider)
  43. if err != nil {
  44. return nil, err
  45. }
  46. // Parse cache configuration with defaults
  47. cacheTTL := 5 * time.Minute
  48. listTTL := 1 * time.Minute
  49. maxCacheSize := int64(1000)
  50. if config != nil {
  51. if ttlStr, ok := config["ttl"].(string); ok && ttlStr != "" {
  52. if parsed, err := time.ParseDuration(ttlStr); err == nil {
  53. cacheTTL = parsed
  54. }
  55. }
  56. if listTTLStr, ok := config["listTtl"].(string); ok && listTTLStr != "" {
  57. if parsed, err := time.ParseDuration(listTTLStr); err == nil {
  58. listTTL = parsed
  59. }
  60. }
  61. if maxSize, ok := config["maxCacheSize"].(int); ok && maxSize > 0 {
  62. maxCacheSize = int64(maxSize)
  63. }
  64. }
  65. // Create adapter and generic cached store
  66. adapter := NewRoleStoreAdapter(filerStore)
  67. cachedStore := util.NewCachedStore(
  68. adapter,
  69. genericCopyRoleDefinition, // Copy function
  70. util.CachedStoreConfig{
  71. TTL: cacheTTL,
  72. ListTTL: listTTL,
  73. MaxCacheSize: maxCacheSize,
  74. },
  75. )
  76. glog.V(2).Infof("Initialized GenericCachedRoleStore with TTL %v, List TTL %v, Max Cache Size %d",
  77. cacheTTL, listTTL, maxCacheSize)
  78. return &GenericCachedRoleStore{
  79. CachedStore: cachedStore,
  80. adapter: adapter,
  81. }, nil
  82. }
  83. // StoreRole implements RoleStore interface
  84. func (c *GenericCachedRoleStore) StoreRole(ctx context.Context, filerAddress string, roleName string, role *RoleDefinition) error {
  85. return c.Store(ctx, filerAddress, roleName, role)
  86. }
  87. // GetRole implements RoleStore interface
  88. func (c *GenericCachedRoleStore) GetRole(ctx context.Context, filerAddress string, roleName string) (*RoleDefinition, error) {
  89. return c.Get(ctx, filerAddress, roleName)
  90. }
  91. // ListRoles implements RoleStore interface
  92. func (c *GenericCachedRoleStore) ListRoles(ctx context.Context, filerAddress string) ([]string, error) {
  93. return c.List(ctx, filerAddress)
  94. }
  95. // DeleteRole implements RoleStore interface
  96. func (c *GenericCachedRoleStore) DeleteRole(ctx context.Context, filerAddress string, roleName string) error {
  97. return c.Delete(ctx, filerAddress, roleName)
  98. }
  99. // genericCopyRoleDefinition creates a deep copy of a RoleDefinition for the generic cache
  100. func genericCopyRoleDefinition(role *RoleDefinition) *RoleDefinition {
  101. if role == nil {
  102. return nil
  103. }
  104. result := &RoleDefinition{
  105. RoleName: role.RoleName,
  106. RoleArn: role.RoleArn,
  107. Description: role.Description,
  108. }
  109. // Deep copy trust policy if it exists
  110. if role.TrustPolicy != nil {
  111. trustPolicyData, err := json.Marshal(role.TrustPolicy)
  112. if err != nil {
  113. glog.Errorf("Failed to marshal trust policy for deep copy: %v", err)
  114. return nil
  115. }
  116. var trustPolicyCopy policy.PolicyDocument
  117. if err := json.Unmarshal(trustPolicyData, &trustPolicyCopy); err != nil {
  118. glog.Errorf("Failed to unmarshal trust policy for deep copy: %v", err)
  119. return nil
  120. }
  121. result.TrustPolicy = &trustPolicyCopy
  122. }
  123. // Deep copy attached policies slice
  124. if role.AttachedPolicies != nil {
  125. result.AttachedPolicies = make([]string, len(role.AttachedPolicies))
  126. copy(result.AttachedPolicies, role.AttachedPolicies)
  127. }
  128. return result
  129. }