1
+ import * as clc from "colorette" ;
2
+
1
3
import { Options } from "../../options" ;
2
4
import {
3
5
firebaseowner ,
@@ -8,18 +10,17 @@ import {
8
10
readerRolePermissions ,
9
11
defaultPermissions ,
10
12
FIREBASE_SUPER_USER ,
11
- CLOUDSQL_SUPER_USER ,
12
13
} from "./permissions" ;
13
14
import { iamUserIsCSQLAdmin } from "./cloudsqladmin" ;
14
15
import { setupIAMUsers } from "./connect" ;
15
16
import { logger } from "../../logger" ;
16
17
import { confirm } from "../../prompt" ;
17
- import * as clc from "colorette" ;
18
18
import { FirebaseError } from "../../error" ;
19
19
import { needProjectNumber } from "../../projectUtils" ;
20
20
import { executeSqlCmdsAsIamUser , executeSqlCmdsAsSuperUser , getIAMUser } from "./connect" ;
21
21
import { concat } from "lodash" ;
22
22
import { getDataConnectP4SA , toDatabaseUser } from "./connect" ;
23
+ import * as utils from "../../utils" ;
23
24
24
25
export type TableMetadata = {
25
26
name : string ;
@@ -104,9 +105,10 @@ export async function setupSQLPermissions(
104
105
options : Options ,
105
106
silent : boolean = false ,
106
107
) : Promise < SchemaSetupStatus . BrownField | SchemaSetupStatus . GreenField > {
108
+ const logFn = silent ? logger . debug : ( message : string ) => { return utils . logLabeledBullet ( 'dataconnect' , message ) } ;
107
109
const schema = schemaInfo . name ;
108
110
// Step 0: Check current user can run setup and upsert IAM / P4SA users
109
- logger . info (
111
+ logFn (
110
112
`Detected schema "${ schema } " setup status is ${ schemaInfo . setupStatus } . Running setup...` ,
111
113
) ;
112
114
@@ -121,14 +123,14 @@ export async function setupSQLPermissions(
121
123
let runGreenfieldSetup = false ;
122
124
if ( schemaInfo . setupStatus === SchemaSetupStatus . GreenField ) {
123
125
runGreenfieldSetup = true ;
124
- logger . info (
126
+ logFn (
125
127
`Database ${ databaseId } has already been setup as greenfield project. Rerunning setup to repair any missing permissions.` ,
126
128
) ;
127
129
}
128
130
129
131
if ( schemaInfo . tables . length === 0 ) {
130
132
runGreenfieldSetup = true ;
131
- logger . info ( `Found no tables in schema "${ schema } ", assuming greenfield project.` ) ;
133
+ logFn ( `Found no tables in schema "${ schema } ", assuming greenfield project.` ) ;
132
134
}
133
135
134
136
// We need to setup the database
@@ -148,7 +150,7 @@ export async function setupSQLPermissions(
148
150
/** transaction=*/ true ,
149
151
) ;
150
152
151
- logger . info ( clc . green ( "Database setup complete." ) ) ;
153
+ logFn ( clc . green ( "Database setup complete." ) ) ;
152
154
return SchemaSetupStatus . GreenField ;
153
155
}
154
156
@@ -158,7 +160,7 @@ export async function setupSQLPermissions(
158
160
) ;
159
161
}
160
162
const currentTablesOwners = [ ...new Set ( schemaInfo . tables . map ( ( t ) => t . owner ) ) ] ;
161
- logger . info (
163
+ logFn (
162
164
`We found some existing object owners [${ currentTablesOwners . join ( ", " ) } ] in your cloudsql "${ schema } " schema.` ,
163
165
) ;
164
166
@@ -173,22 +175,22 @@ export async function setupSQLPermissions(
173
175
174
176
if ( shouldSetupGreenfield ) {
175
177
await setupBrownfieldAsGreenfield ( instanceId , databaseId , schemaInfo , options , silent ) ;
176
- logger . info ( clc . green ( "Database setup complete." ) ) ;
177
- logger . info (
178
+ logger . info ( clc . green ( "Database setup complete." ) ) ; // If we do set up, always at least show this line.
179
+ logFn (
178
180
clc . yellow (
179
181
"IMPORTANT: please uncomment 'schemaValidation: \"COMPATIBLE\"' in your dataconnect.yaml file to avoid dropping any existing tables by mistake." ,
180
182
) ,
181
183
) ;
182
184
return SchemaSetupStatus . GreenField ;
183
185
} else {
184
- logger . info (
186
+ logFn (
185
187
clc . yellow (
186
188
"Setting up database in brownfield mode.\n" +
187
189
`Note: SQL migrations can't be done through ${ clc . bold ( "firebase dataconnect:sql:migrate" ) } in this mode.` ,
188
190
) ,
189
191
) ;
190
192
await brownfieldSqlSetup ( instanceId , databaseId , schemaInfo , options , silent ) ;
191
- logger . info ( clc . green ( "Brownfield database setup complete." ) ) ;
193
+ logFn ( clc . green ( "Brownfield database setup complete." ) ) ;
192
194
return SchemaSetupStatus . BrownField ;
193
195
}
194
196
}
@@ -326,13 +328,6 @@ export async function getSchemaMetadata(
326
328
} ;
327
329
}
328
330
329
- function filterTableOwners ( schemaInfo : SchemaMetadata , databaseId : string ) {
330
- return [ ...new Set ( schemaInfo . tables . map ( ( t ) => t . owner ) ) ] . filter (
331
- ( owner ) =>
332
- owner !== CLOUDSQL_SUPER_USER && owner !== firebaseowner ( databaseId , schemaInfo . name ) ,
333
- ) ;
334
- }
335
-
336
331
export async function setupBrownfieldAsGreenfield (
337
332
instanceId : string ,
338
333
databaseId : string ,
@@ -343,21 +338,23 @@ export async function setupBrownfieldAsGreenfield(
343
338
const schema = schemaInfo . name ;
344
339
345
340
const firebaseOwnerRole = firebaseowner ( databaseId , schema ) ;
346
- const uniqueTablesOwners = filterTableOwners ( schemaInfo , databaseId ) ;
341
+ const nonFirebasetablesOwners = [ ...new Set ( schemaInfo . tables . map ( ( t ) => t . owner ) ) ] . filter (
342
+ ( owner ) => owner !== firebaseOwnerRole ,
343
+ ) ;
347
344
348
345
// Grant roles to firebase superuser to avoid missing permissions on tables
349
- const grantOwnersToSuperuserCmds = uniqueTablesOwners . map (
346
+ const grantOwnersToSuperuserCmds = nonFirebasetablesOwners . map (
350
347
( owner ) => `GRANT "${ owner } " TO "${ FIREBASE_SUPER_USER } "` ,
351
348
) ;
352
- const revokeOwnersFromSuperuserCmds = uniqueTablesOwners . map (
349
+ const revokeOwnersFromSuperuserCmds = nonFirebasetablesOwners . map (
353
350
( owner ) => `REVOKE "${ owner } " FROM "${ FIREBASE_SUPER_USER } "` ,
354
351
) ;
355
352
356
353
// Step 1: Our usual setup which creates necessary roles, transfers schema ownership, and gives nessary grants.
357
354
const greenfieldSetupCmds = await greenFieldSchemaSetup ( instanceId , databaseId , schema , options ) ;
358
355
359
356
// Step 2: Grant non firebase owners the writer role before changing the table owners.
360
- const grantCmds = uniqueTablesOwners . map (
357
+ const grantCmds = nonFirebasetablesOwners . map (
361
358
( owner ) => `GRANT "${ firebasewriter ( databaseId , schema ) } " TO "${ owner } "` ,
362
359
) ;
363
360
@@ -394,8 +391,8 @@ export async function brownfieldSqlSetup(
394
391
) {
395
392
const schema = schemaInfo . name ;
396
393
397
- // Step 1: Grant firebasesuperuser access to the original owner.
398
- const uniqueTablesOwners = filterTableOwners ( schemaInfo , databaseId ) ;
394
+ // Step 1: Grant firebasesuperuser access to the original owner
395
+ const uniqueTablesOwners = [ ... new Set ( schemaInfo . tables . map ( ( t ) => t . owner ) ) ] ;
399
396
const grantOwnersToFirebasesuperuser = uniqueTablesOwners . map (
400
397
( owner ) => `GRANT "${ owner } " TO "${ FIREBASE_SUPER_USER } "` ,
401
398
) ;
0 commit comments