@@ -4,9 +4,14 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
+ "net/url"
7
8
"strings"
8
9
"sync"
9
10
11
+ "github.com/hashicorp/go-multierror"
12
+ "gorm.io/driver/postgres"
13
+ "gorm.io/gorm"
14
+
10
15
"get.porter.sh/porter/pkg/build"
11
16
"get.porter.sh/porter/pkg/build/buildkit"
12
17
"get.porter.sh/porter/pkg/cache"
@@ -22,9 +27,9 @@ import (
22
27
"get.porter.sh/porter/pkg/storage"
23
28
"get.porter.sh/porter/pkg/storage/migrations"
24
29
storageplugin "get.porter.sh/porter/pkg/storage/pluginstore"
30
+ "get.porter.sh/porter/pkg/storage/sql"
25
31
"get.porter.sh/porter/pkg/templates"
26
32
"get.porter.sh/porter/pkg/tracing"
27
- "github.com/hashicorp/go-multierror"
28
33
)
29
34
30
35
// Porter is the logic behind the porter client.
@@ -47,22 +52,63 @@ type Porter struct {
47
52
Plugins plugins.PluginProvider
48
53
CNAB cnabprovider.CNABProvider
49
54
Secrets secrets.Store
50
- Storage storage.Provider
51
55
Signer signing.Signer
56
+
57
+ // Deprecated: Use the individual storage providers in the Porter struct instead
58
+ // This is only here for backwards compatibility where MongoDB was the only storage provider.
59
+ Storage storage.Provider
60
+ }
61
+
62
+ // Options for configuring a new Porter client passed to NewWith.
63
+ type Options struct {
64
+ Config * config.Config // Optional. Defaults to a config.New.
65
+ SecretStorage secrets.Store // Optional. Defaults to a secrets.NewPluginAdapter(secretsplugin.NewStore).
66
+ Signer signing.Signer // Optional. Defaults to a signing.NewPluginAdapter(signingplugin.NewSigner).
67
+ }
68
+
69
+ // NewWith creates a new Porter client with useful defaults that can be overridden with the provided options.
70
+ func NewWith (opt Options ) (* Porter , error ) {
71
+ if opt .Config == nil {
72
+ opt .Config = config .New ()
73
+ }
74
+ if opt .SecretStorage == nil {
75
+ opt .SecretStorage = secrets .NewPluginAdapter (secretsplugin .NewStore (opt .Config ))
76
+ }
77
+ if opt .Signer == nil {
78
+ opt .Signer = signing .NewPluginAdapter (signingplugin .NewSigner (opt .Config ))
79
+ }
80
+
81
+ if p , ok := sql .IsPostgresStorage (opt .Config ); ok {
82
+ po , err := newWithSQL (opt .Config , p , opt .SecretStorage , opt .Signer )
83
+ if err != nil {
84
+ return nil , err
85
+ }
86
+ return po , nil
87
+ }
88
+
89
+ storage := storage .NewPluginAdapter (storageplugin .NewStore (opt .Config ))
90
+ return newFor (opt .Config , storage , opt .SecretStorage , opt .Signer ), nil
52
91
}
53
92
54
93
// New porter client, initialized with useful defaults.
94
+ //
95
+ // Deprecated: Use NewWith instead. New does not support SQL storage backends.
55
96
func New () * Porter {
56
97
c := config .New ()
57
- storage := storage . NewPluginAdapter ( storageplugin . NewStore ( c ))
98
+
58
99
secretStorage := secrets .NewPluginAdapter (secretsplugin .NewStore (c ))
59
100
signer := signing .NewPluginAdapter (signingplugin .NewSigner (c ))
60
- return NewFor (c , storage , secretStorage , signer )
61
- }
62
101
63
- func NewFor (c * config.Config , store storage.Store , secretStorage secrets.Store , signer signing.Signer ) * Porter {
64
- cache := cache .New (c )
102
+ storage := storage .NewPluginAdapter (storageplugin .NewStore (c ))
103
+ return newFor (c , storage , secretStorage , signer )
104
+ }
65
105
106
+ func newFor (
107
+ c * config.Config ,
108
+ store storage.Store ,
109
+ secretStorage secrets.Store ,
110
+ signer signing.Signer ,
111
+ ) * Porter {
66
112
storageManager := migrations .NewManager (c , store )
67
113
installationStorage := storage .NewInstallationStore (storageManager )
68
114
credStorage := storage .NewCredentialStore (storageManager , secretStorage )
@@ -71,9 +117,53 @@ func NewFor(c *config.Config, store storage.Store, secretStorage secrets.Store,
71
117
72
118
storageManager .Initialize (sanitizerService ) // we have a bit of a dependency problem here that it would be great to figure out eventually
73
119
120
+ return newWith (c , installationStorage , credStorage , paramStorage , secretStorage , signer , sanitizerService , storageManager )
121
+ }
122
+
123
+ func newWithSQL (
124
+ c * config.Config ,
125
+ p config.StoragePlugin ,
126
+ secretStorage secrets.Store ,
127
+ signer signing.Signer ,
128
+ ) (* Porter , error ) {
129
+ pc , err := sql .UnmarshalPluginConfig (p .GetConfig ())
130
+ if err != nil {
131
+ return nil , fmt .Errorf ("could not unmarshal plugin config: %s" , err )
132
+ }
133
+ if pc .URL == "" {
134
+ return nil , errors .New ("no URL provided in plugin config" )
135
+ }
136
+ _ , err = url .Parse (pc .URL )
137
+ if err != nil {
138
+ return nil , fmt .Errorf ("invalid URL provided in plugin config: %s" , err )
139
+ }
140
+ db , err := gorm .Open (postgres .Open (pc .URL ))
141
+ if err != nil {
142
+ return nil , fmt .Errorf ("could not open database: %s" , err )
143
+ }
144
+
145
+ installationStorage := storage .NewInstallationStoreSQL (db )
146
+ credStorage := storage .NewCredentialStoreSQL (db , secretStorage )
147
+ paramStorage := storage .NewParameterStoreSQL (db , secretStorage )
148
+ sanitizerService := storage .NewSanitizer (paramStorage , secretStorage )
149
+
150
+ return newWith (c , installationStorage , credStorage , paramStorage , secretStorage , signer , sanitizerService , nil ), nil
151
+ }
152
+
153
+ func newWith (
154
+ c * config.Config ,
155
+ installationStorage storage.InstallationProvider ,
156
+ credStorage storage.CredentialSetProvider ,
157
+ paramStorage storage.ParameterSetProvider ,
158
+ secretStorage secrets.Store ,
159
+ signer signing.Signer ,
160
+ sanitizerService * storage.Sanitizer ,
161
+ storageManager storage.Provider ,
162
+ ) * Porter {
163
+
74
164
return & Porter {
75
165
Config : c ,
76
- Cache : cache ,
166
+ Cache : cache . New ( c ) ,
77
167
Storage : storageManager ,
78
168
Installations : installationStorage ,
79
169
Credentials : credStorage ,
@@ -129,9 +219,11 @@ func (p *Porter) Close() error {
129
219
bigErr = multierror .Append (bigErr , err )
130
220
}
131
221
132
- err = p .Storage .Close ()
133
- if err != nil {
134
- bigErr = multierror .Append (bigErr , err )
222
+ if p .Storage != nil {
223
+ err = p .Storage .Close ()
224
+ if err != nil {
225
+ bigErr = multierror .Append (bigErr , err )
226
+ }
135
227
}
136
228
137
229
err = p .Config .Close ()
0 commit comments