/
databaseclaim_types.go
390 lines (301 loc) · 13.5 KB
/
databaseclaim_types.go
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"fmt"
"net/url"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
type DatabaseType string
const (
Postgres DatabaseType = "postgres"
MySQL DatabaseType = "mysql"
Aurora DatabaseType = "aurora"
)
type SQLEngine string
// SQL database engines.
const (
MysqlEngine SQLEngine = "mysql"
PostgresqlEngine SQLEngine = "postgres"
)
type SourceDataType string
const (
DatabaseSource SourceDataType = "database"
S3Source SourceDataType = "s3"
)
type DeletionPolicy string
const (
// Delete the database instance when the resource is deleted.
DeleteDeletionPolicy DeletionPolicy = "Delete"
// Retain the database instance when the resource is deleted.
OrphanDeletionPolicy DeletionPolicy = "Orphan"
)
// SourceDataFrom is a union object for specifying the initial state of a DB that should be used when provisioning a DatabaseClaim
type SourceDataFrom struct {
// Type specifies the type of source
// +required
Type SourceDataType `json:"type"`
// Database defines the connection information to an existing db
// +optional
Database *Database `json:"database,omitempty"`
// S3 defines the location of a DB backup in an S3 bucket
// +optional
S3 *S3BackupConfiguration `json:"s3,omitempty"`
}
// S3BackupConfiguration defines the details of the S3 backup to restore from.
type S3BackupConfiguration struct {
// +required
Region string `json:"region"`
// +required
Bucket string `json:"bucket"`
// Prefix is the path prefix of the S3 bucket within which the backup to restore is located.
// +optional
Prefix *string `json:"prefix,omitempty"`
// SourceEngine is the engine used to create the backup.
SourceEngine *SQLEngine `json:"sourceEngine"`
// SourceEngineVersion is the version of the engine used to create the backup.
// Example: "5.7.30"
SourceEngineVersion *string `json:"sourceEngineVersion"`
// SecretRef specifies a secret to use for connecting to the s3 bucket via AWS client
// TODO: document/validate the secret format required
// +optional
SecretRef *SecretRef `json:"secretRef,omitempty"`
}
// Database defines the details of an existing database to use as a backup restoration source
type Database struct {
// DSN is the connection string used to reach the postgres database
// must have protocol specifier at beginning (example: mysql:// postgres:// )
DSN string `json:"dsn"`
// SecretRef specifies a secret to use for connecting to the postgresdb (should be master/root)
// TODO: document/validate the secret format required
// +optional
SecretRef *SecretRef `json:"secretRef,omitempty"`
}
// SecretRef provides the information necessary to reference a Kubernetes Secret
type SecretRef struct {
Namespace string `json:"namespace,omitempty"`
Name string `json:"name"`
}
// DatabaseClaimSpec defines the desired state of DatabaseClaim
type DatabaseClaimSpec struct {
// Class is used to run multiple instances of dbcontroller.
// +optional
// +kubebuilder:default:="default"
Class *string `json:"class"`
// SourceDataFrom specifies an existing database or backup to use when initially provisioning the database.
// if the dbclaim has already provisioned a database, this field is ignored
// +optional
SourceDataFrom *SourceDataFrom `json:"sourceDataFrom,omitempty"`
// UseExistingSource instructs the controller to perform user management on the database currently defined in the SourceDataFrom field.
// If sourceDataFrom is empty, this is ignored
// If this is set, .sourceDataFrom.Type and .type must match to use an existing source (since they must be the same)
// If this field was set and becomes unset, migration of data will commence
// +optional
// +kubebuilder:default:=false
UseExistingSource *bool `json:"useExistingSource"`
// Specifies an indentifier for the application using the database.
AppID string `json:"appId"`
// Specifies the type of database to provision. Only postgres is supported.
// +required
Type DatabaseType `json:"type"`
// In most cases the AppID will match the database name. In some cases, however, we will need to provide an optional override.
DBNameOverride string `json:"dbNameOverride,omitempty"`
// Specifies the type of deletion policy to use when the resource is deleted.
// It makes a lot of sense to not set it for most cases - this will default it to Orphan based on defaultDeletionPolicy in controllerConfig
// If you are setting it to Delete, you should be aware that the database will be deleted when the resource is deleted. Hope you know what you are doing.
// +optional
// +kubebuilder:validation:Enum=Delete;delete;Orphan;orphan
DeletionPolicy DeletionPolicy `json:"deletionPolicy,omitempty"`
// If provided, marks auto storage scalling to true for postgres DBinstance. The value represents the maximum allowed storage to scale upto.
// For auroraDB instance, this value is ignored.
MaxStorageGB int64 `json:"maxStorageGB,omitempty"`
// The name of the secret to use for storing the ConnectionInfo. Must follow a naming convention that ensures it is unique.
SecretName string `json:"secretName,omitempty"`
// The matching fragment key name of the database instance that will host the database.
InstanceLabel string `json:"instanceLabel,omitempty"`
// The username that the application will use for accessing the database.
Username string `json:"userName"`
// The optional host name where the database instance is located.
// If the value is omitted, then the host value from the matching InstanceLabel will be used.
// +optional
Host string `json:"host,omitempty"`
// The optional port to use for connecting to the host.
// If the value is omitted, then the host value from the matching InstanceLabel will be used.
// +optional
Port string `json:"port,omitempty"`
// The name of the database within InstanceLabel.
// +required
DatabaseName string `json:"databaseName"`
// The version of the database.
// +optional
DBVersion string `json:"dbVersion"`
// DSN key name.
DSNName string `json:"dsnName"`
// The optional Shape values are arbitrary and help drive instance selection
// +optional
Shape string `json:"shape"`
// The optional MinStorageGB value requests the minimum database host storage capacity in GBytes
// +optional
MinStorageGB int `json:"minStorageGB"`
// BackupPolicy specifies the duration at which db backups are taken
// +optional
// +kubebuilder:validation:Enum=Bronze;Silver;Gold;Platinum
BackupPolicy string `json:"backupPolicy,omitempty"`
// RestoreFrom indicates the snapshot to restore the Database from
// +optional
RestoreFrom string `json:"restoreFrom,omitempty"`
// EnableReplicationRole will grant rds replication role to Username
// This value is ignored if EnableSuperUser is set to true
// +optional
// +kubebuilder:default:=false
EnableReplicationRole *bool `json:"enableReplicationRole"`
// EnableSuperUser will grant rds_superuser and createrole role to Username
// This value is ignored if {{ .Values.controllerConfig.supportSuperUserElevation }} is set to false
// +optional
// +kubebuilder:default:=false
EnableSuperUser *bool `json:"enableSuperUser"`
// Tags
// +optional
// +nullable
Tags []Tag `json:"tags,omitempty"`
}
// Tag
type Tag struct {
Key string `json:"key"`
Value string `json:"value"`
}
// DatabaseClaimStatus defines the observed state of DatabaseClaim
type DatabaseClaimStatus struct {
// Any errors related to provisioning this claim.
Error string `json:"error,omitempty"`
//track the status of new db in the process of being created
NewDB Status `json:"newDB,omitempty"`
//track the status of the active db being used by the application
ActiveDB Status `json:"activeDB,omitempty"`
//tracks status of DB migration. if empty, not started.
//non empty denotes migration in progress, unless it is S_Completed
MigrationState string `json:"migrationState,omitempty"`
// tracks the DB which is migrated and not more operational
OldDB StatusForOldDB `json:"oldDB,omitempty"`
}
type StatusForOldDB struct {
// Time the connection info was updated/created.
ConnectionInfo *DatabaseClaimConnectionInfo `json:"connectionInfo,omitempty"`
// Version of the provisioned Database
DBVersion string `json:"dbversion,omitempty"`
// The optional Shape values are arbitrary and help drive instance selection
Shape string `json:"shape,omitempty"`
// Specifies the type of database to provision. Only postgres is supported.
Type DatabaseType `json:"type,omitempty"`
// Time at the process of post migration actions initiated
PostMigrationActionStartedAt *metav1.Time `json:"postMigrationActionStartedAt,omitempty"`
// DbState of the DB. inprogress, "", ready
DbState DbState `json:"DbState,omitempty"`
// The optional MinStorageGB value requests the minimum database host storage capacity in GBytes
MinStorageGB int `json:"minStorageGB,omitempty"`
}
type Status struct {
// Time the database was created
DbCreatedAt *metav1.Time `json:"dbCreateAt,omitempty"`
// The name of the label that was successfully matched against the fragment key names in the db-controller configMap
MatchedLabel string `json:"matchLabel,omitempty"`
ConnectionInfo *DatabaseClaimConnectionInfo `json:"connectionInfo"`
// Version of the provisioned Database
DBVersion string `json:"dbversion,omitempty"`
// The optional Shape values are arbitrary and help drive instance selection
Shape string `json:"shape,omitempty"`
// The optional MinStorageGB value requests the minimum database host storage capacity in GBytes
MinStorageGB int `json:"minStorageGB,omitempty"`
// If provided, marks auto storage scalling to true for postgres DBinstance. The value represents the maximum allowed storage to scale upto.
// For auroraDB instance, this value is ignored.
MaxStorageGB int64 `json:"maxStorageGB,omitempty"`
// Specifies the type of database to provision. Only postgres is supported.
Type DatabaseType `json:"type,omitempty"`
// Time the connection info was updated/created.
ConnectionInfoUpdatedAt *metav1.Time `json:"connectionUpdatedAt,omitempty"`
// Time the user/password was updated/created
UserUpdatedAt *metav1.Time `json:"userUpdatedAt,omitempty"`
// DbState of the DB. inprogress, "", ready
DbState DbState `json:"DbState,omitempty"`
// SourceDataFrom specifies an existing database or backup to use when initially provisioning the database.
// if the dbclaim has already provisioned a database, this field is ignored
// This field used when claim is use-existing-db and attempting to migrate to newdb
// +optional
SourceDataFrom *SourceDataFrom `json:"sourceDataFrom,omitempty"`
}
// DbState keeps track of state of the DB.
type DbState string
const (
Ready DbState = "ready"
InProgress DbState = "in-progress"
UsingExistingDB DbState = "using-existing-db"
UsingSharedHost DbState = "using-shared-host"
PostMigrationInProgress DbState = "post-migration-in-progress"
)
type DatabaseClaimConnectionInfo struct {
Host string `json:"hostName,omitempty"`
Port string `json:"port,omitempty"`
DatabaseName string `json:"databaseName,omitempty"`
Username string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
SSLMode string `json:"sslMode,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="DB",type=string,JSONPath=`.spec.databaseName`
// +kubebuilder:printcolumn:name="State",type=string,JSONPath=`.status.activeDB.DbState`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:printcolumn:name="MigrationState",type="string",priority=1,JSONPath=".status.migrationState"
// +kubebuilder:resource:shortName=dbc
// +kubebuilder:subresource:status
// DatabaseClaim is the Schema for the databaseclaims API
type DatabaseClaim struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DatabaseClaimSpec `json:"spec,omitempty"`
Status DatabaseClaimStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// DatabaseClaimList contains a list of DatabaseClaim
type DatabaseClaimList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []DatabaseClaim `json:"items"`
}
func init() {
SchemeBuilder.Register(&DatabaseClaim{}, &DatabaseClaimList{})
}
func (c *DatabaseClaimConnectionInfo) Uri() string {
return fmt.Sprintf("%s://%s:%s@%s:%s/%s?sslmode=%s", "postgres",
url.QueryEscape(c.Username), url.QueryEscape(c.Password), c.Host, c.Port, url.QueryEscape(c.DatabaseName), c.SSLMode)
}
func ParseUri(dsn string) (*DatabaseClaimConnectionInfo, error) {
c := DatabaseClaimConnectionInfo{}
u, err := url.Parse(dsn)
if err != nil {
return nil, err
}
c.Host = u.Hostname()
c.Port = u.Port()
c.Username = u.User.Username()
c.Password, _ = u.User.Password()
db := strings.Split(u.Path, "/")
if len(db) <= 1 {
return &c, err
}
c.DatabaseName = db[1]
m, _ := url.ParseQuery(u.RawQuery)
c.SSLMode = m.Get("sslmode")
return &c, nil
}