diff --git a/.github/workflows/integration-tests-v2.yml b/.github/workflows/integration-tests-v2.yml index 5001733d05c..a9f149cd022 100644 --- a/.github/workflows/integration-tests-v2.yml +++ b/.github/workflows/integration-tests-v2.yml @@ -7,6 +7,10 @@ on: required: true FIREBOLT_CLIENT_SECRET_STG_NEW_IDN: required: true + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG: + required: true + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG: + required: true inputs: engine-version: description: 'Engine version to use for integration tests' @@ -52,6 +56,8 @@ jobs: env: SERVICE_ID: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }} SERVICE_SECRET: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }} + SERVICE_ID_NO_USER: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG }} + SERVICE_SECRET_NO_USER: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG }} DATABASE_NAME: ${{ steps.setup.outputs.database_name }} ENGINE_NAME: ${{ steps.setup.outputs.engine_name }} STOPPED_ENGINE_NAME: ${{ steps.setup.outputs.stopped_engine_name }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 99836e698b5..6a37c10c8da 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -7,6 +7,10 @@ on: required: true FIREBOLT_CLIENT_SECRET_STG_NEW_IDN: required: true + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG: + required: true + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG: + required: true permissions: contents: read @@ -17,6 +21,8 @@ jobs: secrets: FIREBOLT_CLIENT_ID_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }} FIREBOLT_CLIENT_SECRET_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }} + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG }} + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG }} integration-test-core: uses: ./.github/workflows/integration-tests-core.yml report-test-results: diff --git a/.github/workflows/nightly-v2.yml b/.github/workflows/nightly-v2.yml index c1b4529d4b6..f6ba43d6103 100644 --- a/.github/workflows/nightly-v2.yml +++ b/.github/workflows/nightly-v2.yml @@ -76,6 +76,8 @@ jobs: env: SERVICE_ID: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }} SERVICE_SECRET: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }} + SERVICE_ID_NO_USER: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG }} + SERVICE_SECRET_NO_USER: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG }} DATABASE_NAME: ${{ steps.setup.outputs.database_name }} ENGINE_NAME: ${{ steps.setup.outputs.engine_name }} STOPPED_ENGINE_NAME: ${{ steps.setup.outputs.stopped_engine_name }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8f5f4021cba..9ac505e4ad8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,6 +22,8 @@ jobs: secrets: FIREBOLT_CLIENT_ID_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }} FIREBOLT_CLIENT_SECRET_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }} + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG }} + ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG }} publish: runs-on: ubuntu-latest diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index c47b383a827..30c524047f8 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -17,6 +17,10 @@ API_ENDPOINT_ENV = "API_ENDPOINT" SERVICE_ID_ENV = "SERVICE_ID" SERVICE_SECRET_ENV = "SERVICE_SECRET" +# Pre-provisioned service account that has no user attached, used to check +# that such an account cannot connect +SERVICE_ID_NO_USER_ENV = "SERVICE_ID_NO_USER" +SERVICE_SECRET_NO_USER_ENV = "SERVICE_SECRET_NO_USER" CORE_URL_ENV = "CORE_URL" # Only these values are safe to print. Anything else, including renamed @@ -130,6 +134,13 @@ def auth(service_id: str, service_secret: Secret) -> ClientCredentials: return ClientCredentials(service_id, service_secret.value) +@fixture(scope="session") +def auth_no_user() -> ClientCredentials: + return ClientCredentials( + must_env(SERVICE_ID_NO_USER_ENV), must_env(SERVICE_SECRET_NO_USER_ENV) + ) + + @fixture(scope="session") def core_auth() -> FireboltCore: return FireboltCore() diff --git a/tests/integration/dbapi/async/V2/conftest.py b/tests/integration/dbapi/async/V2/conftest.py index 65a061d4f75..57f443f80ab 100644 --- a/tests/integration/dbapi/async/V2/conftest.py +++ b/tests/integration/dbapi/async/V2/conftest.py @@ -1,5 +1,3 @@ -import random -import string from typing import Any, Callable, Tuple from pytest import fixture @@ -7,8 +5,6 @@ import firebolt.async_db from firebolt.async_db import Connection, connect from firebolt.client.auth.base import Auth -from firebolt.client.auth.client_credentials import ClientCredentials -from tests.integration.conftest import Secret @fixture @@ -96,42 +92,6 @@ async def connection_system_engine_no_db( yield connection -@fixture -async def service_account_no_user( - connection_system_engine_no_db: Connection, - database_name: str, -) -> Tuple[str, Secret]: - # function-level fixture so we need to make sa name is unique - randomness = "".join(random.choices(string.ascii_letters + string.digits, k=2)) - sa_account_name = f"{database_name}_no_user_{randomness}" - async with connection_system_engine_no_db.cursor() as cursor: - await cursor.execute( - f'CREATE SERVICE ACCOUNT "{sa_account_name}" ' - "WITH DESCRIPTION = 'Ecosytem test with no user'" - ) - await cursor.execute(f"CALL fb_GENERATESERVICEACCOUNTKEY('{sa_account_name}')") - # service_account_name, service_account_id, secret - _, s_id, key = await cursor.fetchone() - # Currently this is bugged so retrieve id via a query. FIR-28719 - if not s_id: - await cursor.execute( - "SELECT service_account_id FROM information_schema.service_accounts " - f"WHERE service_account_name='{sa_account_name}'" - ) - s_id = (await cursor.fetchone())[0] - # Wrap in secret to avoid leaking the key in the logs - yield s_id, Secret(key) - await cursor.execute(f'DROP SERVICE ACCOUNT "{sa_account_name}"') - - -@fixture -async def auth_no_user( - service_account_no_user: Tuple[str, Secret], -) -> ClientCredentials: - s_id, s_secret = service_account_no_user - return ClientCredentials(s_id, s_secret.value) - - @fixture async def mixed_case_db_and_engine( connection_system_engine: Connection, diff --git a/tests/integration/dbapi/sync/V2/conftest.py b/tests/integration/dbapi/sync/V2/conftest.py index b8b1e3ab107..56c5a248a41 100644 --- a/tests/integration/dbapi/sync/V2/conftest.py +++ b/tests/integration/dbapi/sync/V2/conftest.py @@ -1,14 +1,10 @@ -import random -import string from typing import Any, Callable, Tuple from pytest import fixture import firebolt.db from firebolt.client.auth.base import Auth -from firebolt.client.auth.client_credentials import ClientCredentials from firebolt.db import Connection, connect -from tests.integration.conftest import Secret @fixture @@ -104,42 +100,6 @@ def connection_system_engine_no_db( yield connection -@fixture -def service_account_no_user( - connection_system_engine_no_db: Connection, - database_name: str, -) -> Tuple[str, Secret]: - # function-level fixture so we need to make sa name is unique - randomness = "".join(random.choices(string.ascii_letters + string.digits, k=2)) - sa_account_name = f"{database_name}_no_user_{randomness}" - with connection_system_engine_no_db.cursor() as cursor: - cursor.execute( - f'CREATE SERVICE ACCOUNT "{sa_account_name}" ' - "WITH DESCRIPTION = 'Ecosytem test with no user'" - ) - cursor.execute(f"CALL fb_GENERATESERVICEACCOUNTKEY('{sa_account_name}')") - # service_account_name, service_account_id, secret - _, s_id, key = cursor.fetchone() - # Currently this is bugged so retrieve id via a query. FIR-28719 - if not s_id: - cursor.execute( - "SELECT service_account_id FROM information_schema.service_accounts " - f"WHERE service_account_name='{sa_account_name}'" - ) - s_id = cursor.fetchone()[0] - # Wrap in secret to avoid leaking the key in the logs - yield s_id, Secret(key) - cursor.execute(f'DROP SERVICE ACCOUNT "{sa_account_name}"') - - -@fixture -def auth_no_user( - service_account_no_user: Tuple[str, Secret], -) -> ClientCredentials: - s_id, s_secret = service_account_no_user - return ClientCredentials(s_id, s_secret.value) - - @fixture def mixed_case_db_and_engine( connection_system_engine: Connection,