Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fdc brownfield setup #8150

Merged
merged 50 commits into from
Mar 11, 2025
Merged

Fdc brownfield setup #8150

merged 50 commits into from
Mar 11, 2025

Conversation

tammam-g
Copy link
Contributor

@tammam-g tammam-g commented Jan 29, 2025

Description

Support brownfield database setup. When we detect the database schema already have other tables (brownfield or greenfield but then a table was added manually) we ask the user if they want to setup the database as greenfield.
1- They say yes -> We transfer schema and table ownerships to firebase roles, and grant previous roles writer access only.
2- They say no -> We setup the database in brownfield mode which means that deployed connectors have writer permissions but SQL migration will stop working through cli.

Note: We should find a way to automatically turn on compat mode when database is setup as greenfield from brownfield to avoid accidentally dropping important tables.

Note 2: I think I can improve the brownfield experience by allowing firebase deploy to run if the database diff isn't incompatible (say only drops tables and remove fields). Right now sql:migrate will fail if database is found as brownfield which will fail firebase deploy.

Scenarios Tested

Fresh greenfield setup

Setup greenfield database from scratch using firebase deploy/sql:migrate -> no change

Brownfield to greenfield setup

I created one database with one table (not owned by firebase) and then user agrees to set it up as greenfield.

Screenshot 2025-01-31 at 4 13 02 PM Screenshot 2025-01-31 at 4 14 41 PM

Brownfield setup test

I create a new database with one table not owned by firebase and firebase isn't setup.
Screenshot 2025-01-31 at 4 30 57 PM

User runs firebase deploy, we then detect it's brownfield and ask the user if they want to setup the database as greenfield. -> User chooses to keep project as brownfield which sets up firebase writer/reader roles and p4sa access but deployment fails.

Screenshot 2025-01-31 at 4 31 38 PM

Confirming the user which has firebase writer role now can edit and select but can't create new tables.
Screenshot 2025-01-31 at 4 31 56 PM

Screenshot 2025-01-31 at 4 37 58 PM

BrownField Default Permissions Test

Finally, I test default permissions when database is setup. Firebase writer/reader should be able to see and edit tables created by other users in the schema ("public") after the setup is done in brownfield mode.

Screenshot 2025-01-31 at 4 40 50 PM

Additional flags test

Trying --force when migrating a brownfield database fails.

Screenshot 2025-01-31 at 4 50 53 PM

Sample Commands

firebase dataconnect:sql:setup

@tammam-g tammam-g requested review from fredzqm and joehan January 31, 2025 21:52
Copy link
Contributor

@fredzqm fredzqm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Excited to have brown field support very soon!

`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT, USAGE ON SEQUENCES TO "${firebaseReaderRole}";`,
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT EXECUTE ON FUNCTIONS TO "${firebaseReaderRole}"`,
`SET ROLE = cloudsqlsuperuser`,
function defaultPermissions(databaseId: string, schema: string, ownerRole: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cleanup.

Would it make sense to port those changes to backend code as well to keep them reasonably aligned?

I know they should do the same thing for green field.

To make this sync easier in the future, it might make sense to split caller logics to separate files.

We can split logics that aren't copied to the backend permissions.go into permissions_setup.ts. It can have getSchemaMetaData‎ , greenFieldSchemaSetup, brownfieldSqlSetup, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to splitting this up into multiple files - I'd love to keep the prompting logic in a separate file from the SQL command logic

Copy link
Contributor Author

@tammam-g tammam-g Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved setupSQLPermissions to the command file dataconnect-sql-setup.ts, this way interactivity is not part of permissions and it's within the command file which makes sense to me. I do import the setupSQLPermissions in schemaMigration.ts but I also feel this make sense, it basically makes it clear that we are running the setup workflow within the migration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commands/** should only have scaffolding for each comment.

Any re-usable logics should be defined in the dataconnect/* package.

For the sake of making it easier to map it to the backend permissions.go, can you move any logics not in backend to a separate file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, split it into two files

`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT, USAGE ON SEQUENCES TO "${firebaseReaderRole}";`,
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT EXECUTE ON FUNCTIONS TO "${firebaseReaderRole}"`,
`SET ROLE = cloudsqlsuperuser`,
function defaultPermissions(databaseId: string, schema: string, ownerRole: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to splitting this up into multiple files - I'd love to keep the prompting logic in a separate file from the SQL command logic

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 23.64865% with 113 lines in your changes missing coverage. Please review.

Project coverage is 51.02%. Comparing base (774d3f0) to head (e928a6b).
Report is 51 commits behind head on master.

Files with missing lines Patch % Lines
src/gcp/cloudsql/permissions.ts 24.35% 59 Missing ⚠️
src/commands/dataconnect-sql-setup.ts 28.84% 37 Missing ⚠️
src/dataconnect/schemaMigration.ts 7.14% 13 Missing ⚠️
src/gcp/cloudsql/connect.ts 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8150      +/-   ##
==========================================
- Coverage   51.10%   51.02%   -0.08%     
==========================================
  Files         423      424       +1     
  Lines       29636    30473     +837     
  Branches     6063     6322     +259     
==========================================
+ Hits        15144    15548     +404     
- Misses      13134    13555     +421     
- Partials     1358     1370      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tammam-g tammam-g requested a review from fredzqm February 12, 2025 17:44
@fredzqm
Copy link
Contributor

fredzqm commented Feb 12, 2025

Note 2: I think I can improve the brownfield experience by allowing firebase deploy to run if the database diff isn't incompatible (say only drops tables and remove fields). Right now sql:migrate will fail if database is found as brownfield which will fail firebase deploy.

It should already work in the way that you want.

sql:migrate talks to backend to determine if there are any diffs. If there are no IncompatibleSchemaError returned, it would actually skip any migration steps. Brown field customer can use firebase deploy to deploy FDC Schema & Connectors as long as there is no diff.

await greenFieldSchemaSetup(instanceId, databaseId, schema, options, silent);
logger.info(clc.green("Database setup complete."));
return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If !rerunSetup, should we abort?

Honestly, don't find this prompt that valuable.

If they run sql:setup, the intent to setup SQL is already clear. It feels redundant to ask them again.

Logging is enough here.

`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT SELECT, USAGE ON SEQUENCES TO "${firebaseReaderRole}";`,
`ALTER DEFAULT PRIVILEGES IN SCHEMA "${schema}" GRANT EXECUTE ON FUNCTIONS TO "${firebaseReaderRole}"`,
`SET ROLE = cloudsqlsuperuser`,
function defaultPermissions(databaseId: string, schema: string, ownerRole: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commands/** should only have scaffolding for each comment.

Any re-usable logics should be defined in the dataconnect/* package.

For the sake of making it easier to map it to the backend permissions.go, can you move any logics not in backend to a separate file?

maneesht and others added 23 commits March 10, 2025 18:09
…s. (#8204)

* Format INTERACTIVE_ACK issues as table as well and add extra "type" column to table.

* Update warning and prompt wording to reflect insecure operations as well as connector evolution issues.

* Wording.

* Sort issues in table by category and some formatting fixes.
* Use correct import path for data connect emulator

* Actually fix it this time

* fix the thing i broke and format

* Update src/emulator/dataconnect/pgliteServer.ts

Co-authored-by: Maneesh Tewani <maneesht@users.noreply.github.com>

---------

Co-authored-by: Maneesh Tewani <maneesht@users.noreply.github.com>
* Don't surface connector evolution or insecure operation issues in VSCode.'

* Fix

* Filter by "INSECURE" substring rather than warningLevel.
…hen env vars for emulators are set (#8231)

* fix bug where apphosting emulator info is not complete when env vars for other emulators are set

* add proper fix and test

* fix

* remove async from non-async test func

* address comments
* Bump FDC local toolkit to v1.8.2.

* Update changelog.
* fix: #8168 - enforce webframeworks only when needed

In deployments where `--only hosting:boo` is used, enforce webframeworks
enablement only when the target actually uses webframeworks.

* remove console

* add changelog, add tests

* Add matchesHostingTarget to improve readability

---------

Co-authored-by: Chalo Salvador <chalo@monogram.io>
…8237)

* Added env var to magically import data connect service from console

* actually check location too

* formats

* Formats
* Improve robustness of function discovery for python

Anecdotally, python function discovery is flakey. We propose 2 change in
this PR:

1. For python discovery, add a small initial delay for python's admin
server to boot.

2. Add a request timeout to retry call to retrieve trigger information.
Previously, the default timeout would've been set to OS-level TCP
timeout, which in my laptop was between 20~30s.

* Add changelog.

* Remove per-req timeout to accomodate loading large/slow main.py.

* Update changelog.

* Revert timeout bump.
* update vscode to 0.13.1

* remove changelog line
* Apply ajv and ajv-formats overrides to shrinkwrap

* Apply whatwg-url override to shrinkwrap

* npm i to stabilize shrinkwrap

---------

Co-authored-by: Joe Hanley <joehanley@google.com>
`--location` will be removed from apphosting commands in the next major CLI release. Before then, the CLI will print a warning about this removal whenever `--location` is used.
@tammam-g tammam-g enabled auto-merge (squash) March 10, 2025 23:14
@tammam-g tammam-g disabled auto-merge March 10, 2025 23:15
@tammam-g tammam-g enabled auto-merge (squash) March 10, 2025 23:18
@tammam-g tammam-g disabled auto-merge March 11, 2025 01:12
@tammam-g tammam-g enabled auto-merge (squash) March 11, 2025 01:13
@tammam-g tammam-g merged commit 1d45035 into master Mar 11, 2025
54 of 55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet