@@ -3,6 +3,8 @@ package internalstorage
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "strings"
7
+ "sync"
6
8
7
9
"gorm.io/gorm"
8
10
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -12,30 +14,14 @@ import (
12
14
)
13
15
14
16
type StorageFactory struct {
15
- db * gorm.DB
16
- AutoMigration * bool
17
- DivisionPolicy DivisionPolicy
18
- Mapper []ResourceMapper
17
+ sync.Mutex
18
+
19
+ db * gorm.DB
20
+ SkipAutoMigration bool
21
+ DivisionPolicy DivisionPolicy
19
22
}
20
23
21
24
func (s * StorageFactory ) AutoMigrate () error {
22
- if s .AutoMigration != nil && * s .AutoMigration {
23
- switch s.DivisionPolicy {
24
- if err := s .db .AutoMigrate (& Resource {}); err != nil {
25
- return err
26
- }
27
- case "" , DivisionPolicyNone :
28
- case DivisionPolicyGroupResource :
29
-
30
- }
31
-
32
- if s .DivisionPolicy == "" || s .DivisionPolicy == DivisionPolicyNone {
33
- if err := s .db .AutoMigrate (& Resource {}); err != nil {
34
- return err
35
- }
36
- }
37
- }
38
-
39
25
return nil
40
26
}
41
27
@@ -44,10 +30,47 @@ func (s *StorageFactory) GetSupportedRequestVerbs() []string {
44
30
}
45
31
46
32
func (s * StorageFactory ) NewResourceStorage (config * storage.ResourceStorageConfig ) (storage.ResourceStorage , error ) {
47
- return & ResourceStorage {
48
- db : s .db ,
49
- codec : config .Codec ,
33
+ s .Lock ()
34
+ defer s .Unlock ()
50
35
36
+ gvr := schema.GroupVersionResource {
37
+ Group : config .StorageGroupResource .Group ,
38
+ Version : config .StorageVersion .Version ,
39
+ Resource : config .StorageGroupResource .Resource ,
40
+ }
41
+ table := s .tableName (gvr )
42
+
43
+ var model interface {}
44
+ switch s .DivisionPolicy {
45
+ case DivisionPolicyGroupResource :
46
+ model = & GroupVersionResource {}
47
+ if ! s .SkipAutoMigration {
48
+ if exist := s .db .Migrator ().HasTable (table ); ! exist {
49
+ if err := s .db .AutoMigrate (& GroupVersionResource {}); err != nil {
50
+ return nil , err
51
+ }
52
+
53
+ err := s .db .Migrator ().RenameTable ("groupversionresources" , table )
54
+ if err != nil {
55
+ return nil , err
56
+ }
57
+ }
58
+ }
59
+ case "" , DivisionPolicyNone :
60
+ model = & Resource {}
61
+ if ! s .SkipAutoMigration {
62
+ if exist := s .db .Migrator ().HasTable (table ); ! exist {
63
+ if err := s .db .AutoMigrate (& Resource {}); err != nil {
64
+ return nil , err
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ return & ResourceStorage {
71
+ db : s .db .Table (table ).Model (model ),
72
+ model : model ,
73
+ codec : config .Codec ,
51
74
storageGroupResource : config .StorageGroupResource ,
52
75
storageVersion : config .StorageVersion ,
53
76
memoryVersion : config .MemoryVersion ,
@@ -64,12 +87,24 @@ func (s *StorageFactory) NewCollectionResourceStorage(cr *internal.CollectionRes
64
87
}
65
88
66
89
func (s * StorageFactory ) GetResourceVersions (ctx context.Context , cluster string ) (map [schema.GroupVersionResource ]map [string ]interface {}, error ) {
90
+ s .Lock ()
91
+ tables , err := s .db .Migrator ().GetTables ()
92
+ if err != nil {
93
+ s .Unlock ()
94
+ return nil , err
95
+ }
96
+ s .Unlock ()
97
+
67
98
var resources []Resource
68
- result := s .db .WithContext (ctx ).Select ("group" , "version" , "resource" , "namespace" , "name" , "resource_version" ).
69
- Where (map [string ]interface {}{"cluster" : cluster }).
70
- Find (& resources )
71
- if result .Error != nil {
72
- return nil , InterpretDBError (cluster , result .Error )
99
+ for _ , table := range tables {
100
+ result := s .db .WithContext (ctx ).
101
+ Table (table ).
102
+ Select ("group" , "version" , "resource" , "namespace" , "name" , "resource_version" ).
103
+ Where (map [string ]interface {}{"cluster" : cluster }).
104
+ Find (& resources )
105
+ if result .Error != nil {
106
+ return nil , InterpretDBError (cluster , result .Error )
107
+ }
73
108
}
74
109
75
110
resourceversions := make (map [schema.GroupVersionResource ]map [string ]interface {})
@@ -91,18 +126,44 @@ func (s *StorageFactory) GetResourceVersions(ctx context.Context, cluster string
91
126
}
92
127
93
128
func (s * StorageFactory ) CleanCluster (ctx context.Context , cluster string ) error {
94
- result := s .db .WithContext (ctx ).Where (map [string ]interface {}{"cluster" : cluster }).Delete (& Resource {})
95
- return InterpretDBError (cluster , result .Error )
129
+ s .Lock ()
130
+ tables , err := s .db .Migrator ().GetTables ()
131
+ if err != nil {
132
+ s .Unlock ()
133
+ return err
134
+ }
135
+ s .Unlock ()
136
+
137
+ for _ , table := range tables {
138
+ result := s .db .WithContext (ctx ).Table (table ).Where (map [string ]interface {}{"cluster" : cluster }).Delete (& Resource {})
139
+ if result .Error != nil {
140
+ return InterpretDBError (cluster , result .Error )
141
+ }
142
+ }
143
+
144
+ return nil
96
145
}
97
146
98
147
func (s * StorageFactory ) CleanClusterResource (ctx context.Context , cluster string , gvr schema.GroupVersionResource ) error {
99
- result := s .db .WithContext (ctx ).Where (map [string ]interface {}{
100
- "cluster" : cluster ,
101
- "group" : gvr .Group ,
102
- "version" : gvr .Version ,
103
- "resource" : gvr .Resource ,
104
- }).Delete (& Resource {})
105
- return InterpretDBError (fmt .Sprintf ("%s/%s" , cluster , gvr ), result .Error )
148
+ err := s .db .Transaction (func (db * gorm.DB ) error {
149
+ result := s .db .WithContext (ctx ).
150
+ Table (s .tableName (gvr )).
151
+ Where (map [string ]interface {}{
152
+ "cluster" : cluster ,
153
+ "group" : gvr .Group ,
154
+ "version" : gvr .Version ,
155
+ "resource" : gvr .Resource ,
156
+ }).
157
+ Delete (& Resource {})
158
+
159
+ if result .Error != nil {
160
+ return result .Error
161
+ }
162
+
163
+ return nil
164
+ })
165
+
166
+ return InterpretDBError (fmt .Sprintf ("%s/%s" , cluster , gvr ), err )
106
167
}
107
168
108
169
func (s * StorageFactory ) GetCollectionResources (ctx context.Context ) ([]* internal.CollectionResource , error ) {
@@ -116,3 +177,22 @@ func (s *StorageFactory) GetCollectionResources(ctx context.Context) ([]*interna
116
177
func (s * StorageFactory ) PrepareCluster (cluster string ) error {
117
178
return nil
118
179
}
180
+
181
+ // GenerateTableFor return table name using gvr string
182
+ func GenerateTableFor (gvr schema.GroupVersionResource ) string {
183
+ if gvr .Group == "" {
184
+ return fmt .Sprintf ("%s_%s" , gvr .Version , gvr .Resource )
185
+ }
186
+
187
+ group := strings .ReplaceAll (gvr .Group , "." , "_" )
188
+ return fmt .Sprintf ("%s_%s_%s" , group , gvr .Version , gvr .Resource )
189
+ }
190
+
191
+ func (s * StorageFactory ) tableName (gvr schema.GroupVersionResource ) string {
192
+ table := "resources"
193
+ if s .DivisionPolicy == DivisionPolicyGroupResource {
194
+ table = GenerateTableFor (gvr )
195
+ }
196
+
197
+ return table
198
+ }
0 commit comments