1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package importer
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/deinterfacer"
"github.com/cortezaproject/corteza-server/pkg/importer"
"github.com/cortezaproject/corteza-server/pkg/rbac"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
)
type (
Importer struct {
namespaces *Namespace
namespaceFinder namespaceFinder
moduleFinder moduleFinder
chartFinder chartFinder
pageFinder pageFinder
permissions importer.PermissionImporter
settings importer.SettingImporter
}
moduleKeeper interface {
Update(*types.Module) (*types.Module, error)
Create(*types.Module) (*types.Module, error)
}
chartKeeper interface {
Update(*types.Chart) (*types.Chart, error)
Create(*types.Chart) (*types.Chart, error)
}
pageKeeper interface {
Update(*types.Page) (*types.Page, error)
Create(*types.Page) (*types.Page, error)
}
recordKeeper interface {
Update(*types.Record) (*types.Record, error)
Create(*types.Record) (*types.Record, error)
}
)
func NewImporter(nsf namespaceFinder, mf moduleFinder, cf chartFinder, pf pageFinder, p importer.PermissionImporter, s importer.SettingImporter) *Importer {
imp := &Importer{
namespaceFinder: nsf,
moduleFinder: mf,
chartFinder: cf,
pageFinder: pf,
permissions: p,
settings: s,
}
if nsf != nil {
imp.namespaces = NewNamespaceImporter(imp)
}
return imp
}
func (imp *Importer) GetNamespaceImporter() *Namespace {
return imp.namespaces
}
func (imp *Importer) GetModuleImporter(handle string) *Module {
return imp.namespaces.modules[handle]
}
func (imp *Importer) GetPageImporter(handle string) *Page {
return imp.namespaces.pages[handle]
}
func (imp *Importer) GetRecordImporter(handle string) *Record {
return imp.namespaces.records[handle]
}
func (imp *Importer) GetChartImporter(handle string) *Chart {
return imp.namespaces.charts[handle]
}
func (imp *Importer) Cast(def interface{}) (err error) {
var nsHandle string
// Solving a special case where namespace is defined as string
// and we're treating value as namespace's handle
deinterfacer.KVsetString(&nsHandle, "namespace", def)
if nsHandle != "" {
delete(def.(map[interface{}]interface{}), "namespace")
if imp.namespaces != nil {
return imp.namespaces.Cast(nsHandle, def)
} else {
return nil
}
}
return deinterfacer.Each(def, func(index int, key string, val interface{}) (err error) {
switch key {
case "namespaces":
if imp.namespaces != nil {
return imp.namespaces.CastSet(val)
}
case "namespace":
if imp.namespaces != nil {
return imp.namespaces.CastSet([]interface{}{val})
}
case "settings":
if imp.settings != nil {
return imp.settings.CastSet(val)
}
case "allow", "deny":
if imp.permissions != nil {
return imp.permissions.CastResourcesSet(key, val)
}
default:
err = fmt.Errorf("unexpected key %q", key)
}
return err
})
}
func (imp *Importer) Store(
ctx context.Context,
nsStore namespaceKeeper,
mStore moduleKeeper,
cStore chartKeeper,
pStore pageKeeper,
rStore recordKeeper,
pk rbac.ImportKeeper,
roles sysTypes.RoleSet,
) (err error) {
if imp.namespaces != nil {
err = imp.namespaces.Store(ctx, nsStore, mStore, cStore, pStore, rStore)
if err != nil {
return fmt.Errorf("could not import namespaces: %w", err)
}
}
// Make sure we properly replace role handles with IDs
if imp.permissions != nil {
_ = roles.Walk(func(role *sysTypes.Role) error {
imp.permissions.UpdateRoles(role.Handle, role.ID)
return nil
})
err = imp.permissions.Store(ctx, pk)
if err != nil {
return fmt.Errorf("could not import permissions: %w", err)
}
}
return nil
}