Skip to content

Commit

Permalink
fix: no password prompt on db update
Browse files Browse the repository at this point in the history
  • Loading branch information
betodealmeida committed Oct 28, 2022
1 parent dfe2ef2 commit 99bde25
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/preset_cli/cli/superset/sync/native/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ def native( # pylint: disable=too-many-locals, too-many-arguments

base_url = URL(external_url_prefix) if external_url_prefix else None

# collecting existing database UUIDs so we know if we're creating or updating
existing_databases = {str(uuid) for uuid in client.get_uuids("database").values()}

# env for Jinja2 templating
env = dict(pair.split("=", 1) for pair in option if "=" in pair) # type: ignore
env["instance"] = url
Expand Down Expand Up @@ -179,7 +182,10 @@ def native( # pylint: disable=too-many-locals, too-many-arguments
config["external_url"] = str(
base_url / str(relative_path),
)
if relative_path.parts[0] == "databases":
if (
relative_path.parts[0] == "databases"
and config["uuid"] not in existing_databases
):
prompt_for_passwords(relative_path, config)
verify_db_connectivity(config)

Expand Down
59 changes: 59 additions & 0 deletions tests/cli/superset/sync/native/command_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def test_native(mocker: MockerFixture, fs: FakeFilesystem) -> None:
"database_name": "GSheets",
"sqlalchemy_uri": "gsheets://",
"is_managed_externally": False,
"uuid": "uuid1",
}
dataset_config = {"table_name": "test", "is_managed_externally": False}
fs.create_file(
Expand Down Expand Up @@ -182,6 +183,7 @@ def test_native(mocker: MockerFixture, fs: FakeFilesystem) -> None:
"preset_cli.cli.superset.sync.native.command.SupersetClient",
)
client = SupersetClient()
client.get_uuids.return_value = {}
import_resources = mocker.patch(
"preset_cli.cli.superset.sync.native.command.import_resources",
)
Expand All @@ -206,6 +208,55 @@ def test_native(mocker: MockerFixture, fs: FakeFilesystem) -> None:
import_resources.assert_has_calls([mock.call(contents, client, False)])


def test_native_password_prompt(mocker: MockerFixture, fs: FakeFilesystem) -> None:
"""
Test the ``native`` command with databases that have masked passwords.
"""
root = Path("/path/to/root")
fs.create_dir(root)
database_config = {
"database_name": "Postgres",
"sqlalchemy_uri": "postgresql://user:XXXXXXXXXX@host:5432/dbname",
"is_managed_externally": False,
"uuid": "uuid1",
}
fs.create_file(
root / "databases/gsheets.yaml",
contents=yaml.dump(database_config),
)

SupersetClient = mocker.patch(
"preset_cli.cli.superset.sync.native.command.SupersetClient",
)
client = SupersetClient()
client.get_uuids.return_value = {}
mocker.patch("preset_cli.cli.superset.sync.native.command.import_resources")
mocker.patch("preset_cli.cli.superset.main.UsernamePasswordAuth")
prompt_for_passwords = mocker.patch(
"preset_cli.cli.superset.sync.native.command.prompt_for_passwords",
)

runner = CliRunner()

result = runner.invoke(
superset_cli,
["https://superset.example.org/", "sync", "native", str(root)],
catch_exceptions=False,
)
assert result.exit_code == 0
prompt_for_passwords.assert_called()

prompt_for_passwords.reset_mock()
client.get_uuids.return_value = {"1": "uuid1"}
result = runner.invoke(
superset_cli,
["https://superset.example.org/", "sync", "native", str(root)],
catch_exceptions=False,
)
assert result.exit_code == 0
prompt_for_passwords.assert_not_called()


def test_native_load_env(
mocker: MockerFixture,
fs: FakeFilesystem,
Expand All @@ -222,6 +273,7 @@ def test_native_load_env(
"database_name": "Postgres",
"sqlalchemy_uri": '{{ env["SQLALCHEMY_URI"] }}',
"is_managed_externally": False,
"uuid": "uuid1",
}
fs.create_file(
root / "databases/postgres.yaml",
Expand All @@ -232,6 +284,7 @@ def test_native_load_env(
"preset_cli.cli.superset.sync.native.command.SupersetClient",
)
client = SupersetClient()
client.get_uuids.return_value = {}
import_resources = mocker.patch(
"preset_cli.cli.superset.sync.native.command.import_resources",
)
Expand All @@ -256,6 +309,7 @@ def test_native_load_env(
"database_name": "Postgres",
"sqlalchemy_uri": "postgres://host1",
"is_managed_externally": False,
"uuid": "uuid1",
},
),
}
Expand All @@ -273,6 +327,7 @@ def test_native_external_url(mocker: MockerFixture, fs: FakeFilesystem) -> None:
"sqlalchemy_uri": "gsheets://",
"external_url": "https://repo.example.com/databases/gsheets.yaml",
"is_managed_externally": True,
"uuid": "uuid1",
}
dataset_config = {
"table_name": "test",
Expand All @@ -292,6 +347,7 @@ def test_native_external_url(mocker: MockerFixture, fs: FakeFilesystem) -> None:
"preset_cli.cli.superset.sync.native.command.SupersetClient",
)
client = SupersetClient()
client.get_uuids.return_value = {}
import_resources = mocker.patch(
"preset_cli.cli.superset.sync.native.command.import_resources",
)
Expand Down Expand Up @@ -378,6 +434,7 @@ def test_template_in_environment(mocker: MockerFixture, fs: FakeFilesystem) -> N
"database_name": "GSheets",
"sqlalchemy_uri": "gsheets://",
"test": "{{ filepath }}",
"uuid": "uuid1",
}
fs.create_file(
root / "databases/gsheets.yaml",
Expand All @@ -388,6 +445,7 @@ def test_template_in_environment(mocker: MockerFixture, fs: FakeFilesystem) -> N
"preset_cli.cli.superset.sync.native.command.SupersetClient",
)
client = SupersetClient()
client.get_uuids.return_value = {}
import_resources = mocker.patch(
"preset_cli.cli.superset.sync.native.command.import_resources",
)
Expand All @@ -407,6 +465,7 @@ def test_template_in_environment(mocker: MockerFixture, fs: FakeFilesystem) -> N
"is_managed_externally": False,
"sqlalchemy_uri": "gsheets://",
"test": "/path/to/root/databases/gsheets.yaml",
"uuid": "uuid1",
},
),
}
Expand Down

0 comments on commit 99bde25

Please sign in to comment.