From 548782a26133f2e6a2dd068621633151fa679116 Mon Sep 17 00:00:00 2001 From: Hugo <10965479+hugoghx@users.noreply.github.com> Date: Fri, 5 Sep 2025 15:03:31 +0100 Subject: [PATCH] refact(db): Redefine credential_vault_library The existing credential_vault_library table is the table that holds operational state for Vault generic credential libraries. This commit renames that table and all its associated database entities to credential_vault_generic_library. Additionally, a new credential_vault_library table is created as the base table for all Vault-subtype credential libraries (eg: Vault generic, Vault SSH Cert). --- .../credential/vault/credential_library.go | 4 +- .../credential/vault/mapping_overriders.go | 6 +- internal/credential/vault/private_library.go | 20 +- internal/credential/vault/query.go | 10 +- .../vault/repository_credential_library.go | 2 +- .../postgres/10/04_vault_credential.up.sql | 2 + .../postgres/22/03_vault_library_map.up.sql | 3 + .../04_vault_library_map_user_password.up.sql | 3 +- ...vault_library_map_username_password.up.sql | 3 +- .../02_vault_ssh_private_key_override.up.sql | 1 + ...1_credential_vault_ssh_cert_library.up.sql | 1 + .../71/15_dynamic_credential_history.up.sql | 1 + .../71/16_recording_dynamic_credential.up.sql | 1 + .../71/17_credential_history_views.up.sql | 3 +- .../81/01_deleted_tables_and_triggers.up.sql | 1 + .../02_username_password_domain_vault.up.sql | 4 + .../oss/postgres/98/04_rdp_targets.up.sql | 1 + ...1_credential_vault_library_refactor.up.sql | 762 +++++++++++ .../migrations/oss/postgres/99/README.md | 50 + .../migrations/oss/postgres_99_01_test.go | 1131 +++++++++++++++++ .../db/sqltest/initdb.d/01_colors_persona.sql | 2 +- .../sqltest/initdb.d/03_widgets_persona.sql | 34 +- .../vault/credential_vault_library.sql | 12 +- ...ential_vault_library_issue_credentials.sql | 8 +- .../credential_vault_library_refactor.sql | 599 +++++++++ ...brary_ssh_private_key_mapping_override.sql | 28 +- ..._username_password_domain_mapping_ovrd.sql | 28 +- ...ary_username_password_mapping_override.sql | 28 +- .../tests/history/dynamic_credentials.sql | 8 +- .../tests/pagination/credential_library.sql | 16 +- .../recording_dynamic_credentials.sql | 4 +- .../session_multiple_sessions.sql | 6 +- .../three_credentials_one_change.sql | 2 +- 33 files changed, 2675 insertions(+), 109 deletions(-) create mode 100644 internal/db/schema/migrations/oss/postgres/99/01_credential_vault_library_refactor.up.sql create mode 100644 internal/db/schema/migrations/oss/postgres/99/README.md create mode 100644 internal/db/schema/migrations/oss/postgres_99_01_test.go create mode 100644 internal/db/sqltest/tests/credential/vault/credential_vault_library_refactor.sql diff --git a/internal/credential/vault/credential_library.go b/internal/credential/vault/credential_library.go index 8345dd1dec..3b49dd6f11 100644 --- a/internal/credential/vault/credential_library.go +++ b/internal/credential/vault/credential_library.go @@ -98,7 +98,7 @@ func (l *CredentialLibrary) TableName() string { if l.tableName != "" { return l.tableName } - return "credential_vault_library" + return "credential_vault_generic_library" } // SetTableName sets the table name. @@ -218,5 +218,5 @@ type deletedCredentialLibrary struct { // TableName returns the tablename to override the default gorm table name func (s *deletedCredentialLibrary) TableName() string { - return "credential_vault_library_deleted" + return "credential_vault_generic_library_deleted" } diff --git a/internal/credential/vault/mapping_overriders.go b/internal/credential/vault/mapping_overriders.go index 0897541027..eef7559e97 100644 --- a/internal/credential/vault/mapping_overriders.go +++ b/internal/credential/vault/mapping_overriders.go @@ -96,7 +96,7 @@ func (o *UsernamePasswordOverride) TableName() string { if o.tableName != "" { return o.tableName } - return "credential_vault_library_username_password_mapping_override" + return "credential_vault_generic_library_username_password_mapping_ovrd" } // SetTableName sets the table name. @@ -163,7 +163,7 @@ func (o *UsernamePasswordDomainOverride) TableName() string { if o.tableName != "" { return o.tableName } - return "credential_vault_library_username_password_domain_mapping_ovrd" + return "credential_vault_generic_library_usern_pass_domain_mapping_ovrd" } // SetTableName sets the table name. @@ -230,7 +230,7 @@ func (o *SshPrivateKeyOverride) TableName() string { if o.tableName != "" { return o.tableName } - return "credential_vault_library_ssh_private_key_mapping_override" + return "credential_vault_generic_library_ssh_private_key_mapping_ovrd" } // SetTableName sets the table name. diff --git a/internal/credential/vault/private_library.go b/internal/credential/vault/private_library.go index 7e1288c7eb..5c1fd0a289 100644 --- a/internal/credential/vault/private_library.go +++ b/internal/credential/vault/private_library.go @@ -231,8 +231,10 @@ type issuingCredentialLibrary interface { retrieveCredential(context.Context, errors.Op, ...credential.Option) (dynamicCred, error) } -// A genericIssuingCredentialLibrary contains all the values needed to connect to Vault and -// retrieve credentials. +// genericIssuingCredentialLibrary is a subtype of +// privateCredentialLibraryAllTypes specifically for Vault generic credential +// libraries. It contains all the values needed to connect to Vault and retrieve +// credentials. type genericIssuingCredentialLibrary struct { PublicId string StoreId string @@ -446,11 +448,6 @@ func (pl *genericIssuingCredentialLibrary) retrieveCredential(ctx context.Contex return convert(ctx, dCred) } -// TableName returns the table name for gorm. -func (pl *genericIssuingCredentialLibrary) TableName() string { - return "credential_vault_library_issue_credentials" -} - func (r *Repository) getIssueCredLibraries(ctx context.Context, requests []credential.Request) ([]issuingCredentialLibrary, error) { const op = "vault.(Repository).getIssueCredLibraries" @@ -514,8 +511,9 @@ func (r *Repository) getIssueCredLibraries(ctx context.Context, requests []crede return decryptedLibs, nil } -// privateCredentialLibraryAllTypes is a clone of genericIssuingCredentialLibrary. Contains -// all the values needed to connect to Vault and retrieve credentials. +// privateCredentialLibraryAllTypes is a type that interfaces with the database. +// It contains all the values needed to connect to Vault and retrieve +// credentials. type privateCredentialLibraryAllTypes struct { PublicId string `gorm:"primary_key"` StoreId string @@ -768,6 +766,10 @@ func (m *requestMap) get(libraryId string) []credential.Purpose { return m.ids[libraryId] } +// sshCertIssuingCredentialLibrary is a subtype of +// privateCredentialLibraryAllTypes specifically for Vault SSH Certificate +// credential libraries. It contains all the values needed to connect to Vault +// and retrieve credentials. type sshCertIssuingCredentialLibrary struct { PublicId string StoreId string diff --git a/internal/credential/vault/query.go b/internal/credential/vault/query.go index b65a1c40ca..de275a2525 100644 --- a/internal/credential/vault/query.go +++ b/internal/credential/vault/query.go @@ -194,7 +194,7 @@ delete from credential_vault_credential select sum(reltuples::bigint) as estimate from pg_class where oid in ( - 'credential_vault_library'::regclass, + 'credential_vault_generic_library'::regclass, 'credential_vault_ssh_cert_library'::regclass ) ` @@ -209,7 +209,7 @@ with libraries as ( ), generic_libs as ( select * - from credential_vault_library + from credential_vault_generic_library where public_id in (select public_id from libraries) ), ssh_cert_libs as ( @@ -280,7 +280,7 @@ with libraries as ( ), generic_libs as ( select * - from credential_vault_library + from credential_vault_generic_library where public_id in (select public_id from libraries) ), ssh_cert_libs as ( @@ -351,7 +351,7 @@ with libraries as ( ), generic_libs as ( select * - from credential_vault_library + from credential_vault_generic_library where public_id in (select public_id from libraries) ), ssh_cert_libs as ( @@ -423,7 +423,7 @@ with libraries as ( ), generic_libs as ( select * - from credential_vault_library + from credential_vault_generic_library where public_id in (select public_id from libraries) ), ssh_cert_libs as ( diff --git a/internal/credential/vault/repository_credential_library.go b/internal/credential/vault/repository_credential_library.go index 9227c5b136..707d64ccf0 100644 --- a/internal/credential/vault/repository_credential_library.go +++ b/internal/credential/vault/repository_credential_library.go @@ -421,7 +421,7 @@ func (pl *listLookupLibrary) toCredentialLibrary() *CredentialLibrary { } // TableName returns the table name for gorm. -func (*listLookupLibrary) TableName() string { return "credential_vault_library_list_lookup" } +func (*listLookupLibrary) TableName() string { return "credential_vault_generic_library_list_lookup" } // GetPublicId returns the public id. func (pl *listLookupLibrary) GetPublicId() string { return pl.PublicId } diff --git a/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql b/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql index 2d109df2e6..7304a5793e 100644 --- a/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql +++ b/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql @@ -264,6 +264,7 @@ begin; ('GET'), ('POST'); + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library ( public_id wt_public_id primary key, store_id wt_public_id not null @@ -379,6 +380,7 @@ begin; ('expired'), ('unknown'); + -- Updated in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_credential ( public_id wt_public_id primary key, library_id wt_public_id diff --git a/internal/db/schema/migrations/oss/postgres/22/03_vault_library_map.up.sql b/internal/db/schema/migrations/oss/postgres/22/03_vault_library_map.up.sql index 8d1877a992..e4e1f0d8ce 100644 --- a/internal/db/schema/migrations/oss/postgres/22/03_vault_library_map.up.sql +++ b/internal/db/schema/migrations/oss/postgres/22/03_vault_library_map.up.sql @@ -3,6 +3,7 @@ begin; + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_mapping_override ( library_id wt_public_id primary key constraint credential_vault_library_fkey @@ -16,6 +17,7 @@ begin; -- insert_credential_vault_library_mapping_override_subtype() is a before insert trigger -- function for subtypes of credential_vault_library_mapping_override + -- Updated and renamed in 99/01_credential_vault_library_refactor.up.sql create function insert_credential_vault_library_mapping_override_subtype() returns trigger as $$ begin @@ -29,6 +31,7 @@ begin; -- delete_credential_vault_library_mapping_override_subtype() is an after delete trigger -- function for subtypes of credential_vault_library_mapping_override + -- Updated and renamed in 99/01_credential_vault_library_refactor.up.sql create function delete_credential_vault_library_mapping_override_subtype() returns trigger as $$ begin diff --git a/internal/db/schema/migrations/oss/postgres/22/04_vault_library_map_user_password.up.sql b/internal/db/schema/migrations/oss/postgres/22/04_vault_library_map_user_password.up.sql index 203b2b13c9..e632287499 100644 --- a/internal/db/schema/migrations/oss/postgres/22/04_vault_library_map_user_password.up.sql +++ b/internal/db/schema/migrations/oss/postgres/22/04_vault_library_map_user_password.up.sql @@ -3,7 +3,8 @@ begin; --- Updated in 36/01_vault_library_map_username_password.up.sql + -- Updated in 36/01_vault_library_map_username_password.up.sql + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_user_password_mapping_override ( library_id wt_public_id primary key constraint credential_vault_library_fkey diff --git a/internal/db/schema/migrations/oss/postgres/36/01_vault_library_map_username_password.up.sql b/internal/db/schema/migrations/oss/postgres/36/01_vault_library_map_username_password.up.sql index 52ea50f95a..b3dfe0145e 100644 --- a/internal/db/schema/migrations/oss/postgres/36/01_vault_library_map_username_password.up.sql +++ b/internal/db/schema/migrations/oss/postgres/36/01_vault_library_map_username_password.up.sql @@ -3,7 +3,8 @@ begin; --- Renames table from 22/04_vault_library_map_user_password.up.sql + -- Renames table from 22/04_vault_library_map_user_password.up.sql + -- Renamed again in 99/01_credential_vault_library_refactor.up.sql alter table credential_vault_library_user_password_mapping_override rename to credential_vault_library_username_password_mapping_override; comment on table credential_vault_library_username_password_mapping_override is diff --git a/internal/db/schema/migrations/oss/postgres/39/02_vault_ssh_private_key_override.up.sql b/internal/db/schema/migrations/oss/postgres/39/02_vault_ssh_private_key_override.up.sql index 268ad9e810..0be0f10c2e 100644 --- a/internal/db/schema/migrations/oss/postgres/39/02_vault_ssh_private_key_override.up.sql +++ b/internal/db/schema/migrations/oss/postgres/39/02_vault_ssh_private_key_override.up.sql @@ -7,6 +7,7 @@ begin; insert into credential_type_enm (name) values ('ssh_private_key'); + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_ssh_private_key_mapping_override ( library_id wt_public_id primary key constraint credential_vault_library_fkey diff --git a/internal/db/schema/migrations/oss/postgres/63/01_credential_vault_ssh_cert_library.up.sql b/internal/db/schema/migrations/oss/postgres/63/01_credential_vault_ssh_cert_library.up.sql index 0b80f50500..5d7393916d 100644 --- a/internal/db/schema/migrations/oss/postgres/63/01_credential_vault_ssh_cert_library.up.sql +++ b/internal/db/schema/migrations/oss/postgres/63/01_credential_vault_ssh_cert_library.up.sql @@ -93,6 +93,7 @@ begin; ('rsa', 3072), ('rsa', 4096); + -- Updated in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_ssh_cert_library ( public_id wt_public_id primary key, store_id wt_public_id not null diff --git a/internal/db/schema/migrations/oss/postgres/71/15_dynamic_credential_history.up.sql b/internal/db/schema/migrations/oss/postgres/71/15_dynamic_credential_history.up.sql index 820ece1ffc..9fb8ffb0e3 100644 --- a/internal/db/schema/migrations/oss/postgres/71/15_dynamic_credential_history.up.sql +++ b/internal/db/schema/migrations/oss/postgres/71/15_dynamic_credential_history.up.sql @@ -37,6 +37,7 @@ begin; 'delete_credential_library_history_subtype() is an after delete trigger ' 'function for subtypes of credential_library_history_base.'; + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_hst ( public_id wt_public_id not null, name wt_name, diff --git a/internal/db/schema/migrations/oss/postgres/71/16_recording_dynamic_credential.up.sql b/internal/db/schema/migrations/oss/postgres/71/16_recording_dynamic_credential.up.sql index c9c614e32f..1f1828fee5 100644 --- a/internal/db/schema/migrations/oss/postgres/71/16_recording_dynamic_credential.up.sql +++ b/internal/db/schema/migrations/oss/postgres/71/16_recording_dynamic_credential.up.sql @@ -33,6 +33,7 @@ begin; 'along with the values of those entities at the time of the recording. ' 'These values are also stored in the BSR file.'; + -- Updated in 99/01_credential_vault_library_refactor.up.sql create function insert_recording_dynamic_credentials() returns trigger as $$ begin diff --git a/internal/db/schema/migrations/oss/postgres/71/17_credential_history_views.up.sql b/internal/db/schema/migrations/oss/postgres/71/17_credential_history_views.up.sql index a5fcd38abf..01f02fedda 100644 --- a/internal/db/schema/migrations/oss/postgres/71/17_credential_history_views.up.sql +++ b/internal/db/schema/migrations/oss/postgres/71/17_credential_history_views.up.sql @@ -66,7 +66,8 @@ group by sspkc.history_id, rsc.recording_id, css.history_id; comment on view credential_static_ssh_private_key_credential_hst_aggregate is 'credential_static_ssh_private_key_credential_hst_aggregate contains the ssh private key credential history data along with its store and purpose data.'; --- Dynamic Credentials +-- Replaced in 99/01_credential_vault_library_refactor.up.sql. Note that this +-- view's name has changed to credential_vault_generic_library_hst_aggregate. create view credential_vault_library_hst_aggregate as select rdc.recording_id, diff --git a/internal/db/schema/migrations/oss/postgres/81/01_deleted_tables_and_triggers.up.sql b/internal/db/schema/migrations/oss/postgres/81/01_deleted_tables_and_triggers.up.sql index 1d65d241db..543f99a92b 100644 --- a/internal/db/schema/migrations/oss/postgres/81/01_deleted_tables_and_triggers.up.sql +++ b/internal/db/schema/migrations/oss/postgres/81/01_deleted_tables_and_triggers.up.sql @@ -118,6 +118,7 @@ begin; 'It is automatically trimmed of records older than 30 days by a job.'; -- Credential libraries + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_deleted ( public_id wt_public_id primary key, delete_time wt_timestamp not null diff --git a/internal/db/schema/migrations/oss/postgres/98/02_username_password_domain_vault.up.sql b/internal/db/schema/migrations/oss/postgres/98/02_username_password_domain_vault.up.sql index 91720c6d2c..429a3cd0df 100644 --- a/internal/db/schema/migrations/oss/postgres/98/02_username_password_domain_vault.up.sql +++ b/internal/db/schema/migrations/oss/postgres/98/02_username_password_domain_vault.up.sql @@ -3,6 +3,7 @@ begin; + -- Renamed in 99/01_credential_vault_library_refactor.up.sql create table credential_vault_library_username_password_domain_mapping_ovrd ( library_id wt_public_id primary key constraint credential_vault_library_fkey @@ -38,6 +39,7 @@ begin; -- Replaces view from 78/01_ssh_signed_certs_additional_valid_principals.up.sql +-- Replaced in 99/01_credential_vault_library_refactor.up.sql drop view credential_vault_library_issue_credentials; create view credential_vault_library_issue_credentials as with @@ -161,6 +163,8 @@ begin; -- Replaces view created in 49/01_vault_credentials.up.sql +-- Replaced in 99/01_credential_vault_library_refactor.up.sql where this +-- view's name changed to credential_vault_generic_library_list_lookup. drop view credential_vault_library_list_lookup; create view credential_vault_library_list_lookup as with diff --git a/internal/db/schema/migrations/oss/postgres/98/04_rdp_targets.up.sql b/internal/db/schema/migrations/oss/postgres/98/04_rdp_targets.up.sql index e16c47e6c9..269f4cb777 100644 --- a/internal/db/schema/migrations/oss/postgres/98/04_rdp_targets.up.sql +++ b/internal/db/schema/migrations/oss/postgres/98/04_rdp_targets.up.sql @@ -355,6 +355,7 @@ begin; -- The whx_credential_dimension_source view shows the current values in the -- operational tables of the credential dimension. -- Replaces whx_credential_dimension_source defined in 71/07_targets.up.sql + -- Replaced in 99/01_credential_vault_library_refactor.up.sql. create view whx_credential_dimension_source as with vault_generic_library as ( select vcl.public_id as public_id, diff --git a/internal/db/schema/migrations/oss/postgres/99/01_credential_vault_library_refactor.up.sql b/internal/db/schema/migrations/oss/postgres/99/01_credential_vault_library_refactor.up.sql new file mode 100644 index 0000000000..501af20cf6 --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/99/01_credential_vault_library_refactor.up.sql @@ -0,0 +1,762 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: BUSL-1.1 + +-- For context, check the README.md in this folder. +begin; + -- Main table. + -- Renames the table defined in 10/04_vault_credential.up.sql + alter table credential_vault_library + rename to credential_vault_generic_library; + + alter table credential_vault_generic_library + rename constraint credential_vault_library_pkey to credential_vault_generic_library_pkey; + + alter table credential_vault_generic_library + rename constraint credential_vault_library_store_id_name_uq to credential_vault_generic_library_store_id_name_uq; + + alter table credential_vault_generic_library + rename constraint credential_vault_library_store_id_public_id_uq to credential_vault_generic_library_store_id_public_id_uq; + + comment on table credential_vault_generic_library is + 'credential_vault_generic_library is a table where each row is a resource that represents a vault generic credential library. ' + 'It is a credential_vault_library subtype and a child table of credential_vault_store.'; + + drop trigger insert_deleted_id on credential_vault_generic_library; + create trigger insert_deleted_id after delete on credential_vault_generic_library + for each row execute procedure insert_deleted_id('credential_vault_generic_library_deleted'); + + insert into oplog_ticket + (name, version) + values + ('credential_vault_generic_library', 1) + on conflict do nothing; + delete from oplog_ticket where name = 'credential_vault_library'; + + + -- History table. + -- Renames the table defined in 71/15_dynamic_credential_history.up.sql + alter table credential_vault_library_hst + rename to credential_vault_generic_library_hst; + + alter table credential_vault_generic_library_hst + rename constraint credential_vault_library_hst_pkey to credential_vault_generic_library_hst_pkey; + + alter table credential_vault_generic_library_hst + rename constraint credential_vault_library_hst_valid_range_excl to credential_vault_generic_library_hst_valid_range_excl; + + comment on table credential_vault_generic_library_hst is + 'credential_vault_generic_library_hst is a history table where each row contains the values from ' + 'a row in the credential_vault_library table during the time range in the valid_range column.'; + + -- Updates the function defined in 71/16_recording_dynamic_credential.up.sql + drop trigger insert_recording_dynamic_credentials on recording_session; + drop function insert_recording_dynamic_credentials(); + create function insert_recording_dynamic_credentials() returns trigger + as $$ + begin + with + session_recording(session_id, recording_id) as ( + select session_id, public_id + from recording_session + where session_id = new.session_id + ), + session_dynamic_creds(library_id, purpose, recording_id) as ( + select library_id, credential_purpose, recording_id + from session_credential_dynamic + join session_recording using (session_id) + ), + library_history(public_id, store_id, library_hst_id, valid_range) as ( + select public_id, store_id, history_id, valid_range + from credential_vault_generic_library_hst + union + select public_id, store_id, history_id, valid_range + from credential_vault_ssh_cert_library_hst + ), + final(recording_id, library_id, store_id, library_hst_id, store_hst_id, cred_purpose) as ( + select sdc.recording_id, lib.public_id, lib.store_id, lib.library_hst_id, store_hst.history_id, sdc.purpose + from library_history as lib + join credential_vault_store_hst as store_hst on lib.store_id = store_hst.public_id + and store_hst.valid_range @> current_timestamp + join session_dynamic_creds as sdc on lib.public_id = sdc.library_id + where lib.public_id in (select library_id from session_dynamic_creds) + and lib.valid_range @> current_timestamp + ) + insert into recording_dynamic_credential + (recording_id, credential_vault_store_hst_id, credential_library_hst_id, credential_purpose) + select recording_id, store_hst_id, library_hst_id, cred_purpose + from final; + return new; + end; + $$ language plpgsql; + comment on function insert_recording_dynamic_credentials is + 'insert_recording_dynamic_credentials is an after insert trigger for the recording_session table.'; + + create trigger insert_recording_dynamic_credentials after insert on recording_session + for each row execute procedure insert_recording_dynamic_credentials(); + + + -- Deleted table. + -- Renames table defined in 81/01_deleted_tables_and_triggers.up.sql + alter table credential_vault_library_deleted + rename to credential_vault_generic_library_deleted; + + alter table credential_vault_generic_library_deleted + rename constraint credential_vault_library_deleted_pkey to credential_vault_generic_library_deleted_pkey; + + alter index credential_vault_library_deleted_delete_time_idx + rename to credential_vault_generic_library_deleted_delete_time_idx; + + comment on table credential_vault_generic_library_deleted is + 'credential_vault_generic_library_deleted holds the ID and delete_time of every deleted Vault credential library. ' + 'It is automatically trimmed of records older than 30 days by a job.'; + + + -- Mapping override base table. + -- Note that table/constraint/trigger names get very long in the mapping + -- overrides section, and Postgres limits us to 64-1 chars by default, so we + -- may have to restrict our naming. + -- Renames table defined in 22/03_vault_library_map.up.sql + alter table credential_vault_library_mapping_override + rename to credential_vault_generic_library_mapping_override; + + alter table credential_vault_generic_library_mapping_override + rename constraint credential_vault_library_mapping_override_pkey to credential_vault_generic_library_mapping_override_pkey; + + alter table credential_vault_generic_library_mapping_override + rename constraint credential_vault_library_fkey to credential_vault_generic_library_fkey; + + comment on table credential_vault_generic_library_mapping_override is + 'credential_vault_generic_library_mapping_override is a base table for the vault generic library mapping override type. ' + 'Each row is owned by a single vault generic library and maps 1-to-1 to a row in one of the vault generic library mapping override subtype tables.'; + + -- These triggers are recreated on each of the tables' specific sections below. + -- Renames and updates function defined in 22/03_vault_library_map.up.sql + drop trigger insert_credential_vault_library_mapping_override_subtype on credential_vault_library_username_password_mapping_override; + drop trigger insert_credential_vault_library_mapping_override_subtype on credential_vault_library_username_password_domain_mapping_ovrd; + drop trigger insert_credential_vault_library_mapping_override_subtype on credential_vault_library_ssh_private_key_mapping_override; + drop function insert_credential_vault_library_mapping_override_subtype; + create function insert_credential_vault_generic_library_mapping_override_subtyp() returns trigger + as $$ + begin + insert into credential_vault_generic_library_mapping_override + (library_id) + values + (new.library_id); + return new; + end; + $$ language plpgsql; + comment on function insert_credential_vault_generic_library_mapping_override_subtyp() is + 'insert_credential_vault_generic_library_mapping_override_subtyp() is a ' + 'before insert trigger function that inserts rows from subtype tables into ' + 'credential_vault_generic_library_mapping_override. It must be used on all ' + 'Vault generic credential library mapping subtype tables.'; + + -- These triggers are recreated on each of the tables' specific sections below. + -- Renames and updates function defined in 22/03_vault_library_map.up.sql + drop trigger delete_credential_vault_library_mapping_override_subtype on credential_vault_library_username_password_mapping_override; + drop trigger delete_credential_vault_library_mapping_override_subtype on credential_vault_library_username_password_domain_mapping_ovrd; + drop trigger delete_credential_vault_library_mapping_override_subtype on credential_vault_library_ssh_private_key_mapping_override; + drop function delete_credential_vault_library_mapping_override_subtype; + create function delete_credential_vault_generic_library_mapping_override_subtyp() returns trigger + as $$ + begin + delete from credential_vault_generic_library_mapping_override + where library_id = old.library_id; + return null; -- result is ignored since this is an after trigger + end; + $$ language plpgsql; + comment on function delete_credential_vault_generic_library_mapping_override_subtyp() is + 'delete_credential_vault_generic_library_mapping_override_subtyp() is a ' + 'before insert trigger function that deletes rows from ' + 'credential_vault_generic_library_mapping_override when they''re deleted ' + 'on the subtype tables. It must be used on all Vault generic credential ' + 'library mapping subtype tables.'; + + + -- Mapping override: SSH PK table. + -- Renames table defined in 39/02_vault_ssh_private_key_override.up.sql + alter table credential_vault_library_ssh_private_key_mapping_override + rename to credential_vault_generic_library_ssh_private_key_mapping_ovrd; + + alter table credential_vault_generic_library_ssh_private_key_mapping_ovrd + rename constraint credential_vault_library_ssh_private_key_mapping_override_pkey to credential_vault_generic_library_ssh_priv_key_mapping_ovrd_pkey; + + alter table credential_vault_generic_library_ssh_private_key_mapping_ovrd + rename constraint credential_vault_library_mapping_override_fkey to credential_vault_generic_library_mapping_override_fkey; + + alter table credential_vault_generic_library_ssh_private_key_mapping_ovrd + rename constraint credential_vault_library_fkey to credential_vault_generic_library_fkey; + + comment on table credential_vault_generic_library_ssh_private_key_mapping_ovrd is + 'credential_vault_generic_library_ssh_private_key_mapping_ovrd is a table ' + 'where each row represents a mapping that overrides the default mapping ' + 'from a generic vault secret to a ssh private key credential type ' + 'for a vault generic credential library.'; + + create trigger insert_credential_vault_generic_library_mapping_override_subtyp before insert on credential_vault_generic_library_ssh_private_key_mapping_ovrd + for each row execute procedure insert_credential_vault_generic_library_mapping_override_subtyp(); + + create trigger delete_credential_vault_generic_library_mapping_override_subtyp after delete on credential_vault_generic_library_ssh_private_key_mapping_ovrd + for each row execute procedure delete_credential_vault_generic_library_mapping_override_subtyp(); + + + -- Mapping override: Username & Password table. + -- Renames table in 36/01_vault_library_map_username_password.up.sql + alter table credential_vault_library_username_password_mapping_override + rename to credential_vault_generic_library_username_password_mapping_ovrd; + + alter table credential_vault_generic_library_username_password_mapping_ovrd + rename constraint credential_vault_library_user_password_mapping_override_pkey to credential_vault_generic_library_usern_pass_mapping_ovrd_pkey; + + alter table credential_vault_generic_library_username_password_mapping_ovrd + rename constraint credential_vault_library_fkey to credential_vault_generic_library_fkey; + + alter table credential_vault_generic_library_username_password_mapping_ovrd + rename constraint credential_vault_library_mapping_override_fkey to credential_vault_generic_library_mapping_override_fkey; + + comment on table credential_vault_generic_library_username_password_mapping_ovrd is + 'credential_vault_generic_library_username_password_mapping_ovrd is a table ' + 'where each row represents a mapping that overrides the default mapping ' + 'from a generic vault secret to a username password credential type ' + 'for a vault generic credential library.'; + + create trigger insert_credential_vault_generic_library_mapping_override_subtyp before insert on credential_vault_generic_library_username_password_mapping_ovrd + for each row execute procedure insert_credential_vault_generic_library_mapping_override_subtyp(); + + create trigger delete_credential_vault_generic_library_mapping_override_subtyp after delete on credential_vault_generic_library_username_password_mapping_ovrd + for each row execute procedure delete_credential_vault_generic_library_mapping_override_subtyp(); + + + -- Mapping override: Username, Password & Domain table. + -- Renames table defined in 98/02_username_password_domain_vault.up.sql + alter table credential_vault_library_username_password_domain_mapping_ovrd + rename to credential_vault_generic_library_usern_pass_domain_mapping_ovrd; + + alter table credential_vault_generic_library_usern_pass_domain_mapping_ovrd + rename constraint credential_vault_library_username_password_domain_mapping__pkey to credential_vault_generic_library_upd_mapping_ovrd_pkey; + + alter table credential_vault_generic_library_usern_pass_domain_mapping_ovrd + rename constraint credential_vault_library_fkey to credential_vault_generic_library_fkey; + + alter table credential_vault_generic_library_usern_pass_domain_mapping_ovrd + rename constraint credential_vault_library_mapping_override_fkey to credential_vault_generic_library_mapping_override_fkey; + + comment on table credential_vault_generic_library_usern_pass_domain_mapping_ovrd is + 'credential_vault_generic_library_usern_pass_domain_mapping_ovrd is a table ' + 'where each row represents a mapping that overrides the default mapping ' + 'from a generic vault secret to a user password domain credential type ' + 'for a vault generic credential library.'; + + create trigger insert_credential_vault_generic_library_mapping_override_subtyp before insert on credential_vault_generic_library_usern_pass_domain_mapping_ovrd + for each row execute procedure insert_credential_vault_generic_library_mapping_override_subtyp(); + + create trigger delete_credential_vault_generic_library_mapping_override_subtyp after delete on credential_vault_generic_library_usern_pass_domain_mapping_ovrd + for each row execute procedure delete_credential_vault_generic_library_mapping_override_subtyp(); + + + -- Views. Postgres already automatically updated them to reference the renamed + -- tables, however these should still be explictly in the migration. + -- > whx_credential_dimension_source + -- > credential_vault_library_issue_credentials + -- > credential_vault_library_list_lookup: Renamed to credential_vault_generic_library_list_lookup. + -- > credential_vault_library_hst_aggregate: Renamed to credential_vault_generic_library_hst_aggregate. + + -- Replaces view defined in 98/04_rdp_targets.up.sql + drop view whx_credential_dimension_source; + create view whx_credential_dimension_source as + with vault_generic_library as ( + select vcl.public_id as public_id, + 'vault generic credential library' as type, + coalesce(vcl.name, 'None') as name, + coalesce(vcl.description, 'None') as description, + vcl.vault_path as vault_path, + vcl.http_method as http_method, + case + when vcl.http_method = 'GET' then 'Not Applicable' + else coalesce(vcl.http_request_body::text, 'None') + end as http_request_body, + 'Not Applicable' as username, + 'Not Applicable' as key_type_and_bits + from credential_vault_generic_library as vcl + ), + vault_ssh_cert_library as ( + select vsccl.public_id as public_id, + 'vault ssh certificate credential library' as type, + coalesce(vsccl.name, 'None') as name, + coalesce(vsccl.description, 'None') as description, + vsccl.vault_path as vault_path, + 'Not Applicable' as http_method, + 'Not Applicable' as http_request_body, + vsccl.username as username, + case + when vsccl.key_type = 'ed25519' then vsccl.key_type + else vsccl.key_type || '-' || vsccl.key_bits::text + end as key_type_and_bits + from credential_vault_ssh_cert_library as vsccl + ), + final as ( + select s.public_id as session_id, + scd.credential_purpose as credential_purpose, + cl.public_id as credential_library_id, + coalesce(vcl.type, vsccl.type) as credential_library_type, + coalesce(vcl.name, vsccl.name) as credential_library_name, + coalesce(vcl.description, vsccl.description) as credential_library_description, + coalesce(vcl.vault_path, vsccl.vault_path) as credential_library_vault_path, + coalesce(vcl.http_method, vsccl.http_method) as credential_library_vault_http_method, + coalesce(vcl.http_request_body, vsccl.http_request_body) as credential_library_vault_http_request_body, + coalesce(vcl.username, vsccl.username) as credential_library_username, + coalesce(vcl.key_type_and_bits, vsccl.key_type_and_bits) as credential_library_key_type_and_bits, + cs.public_id as credential_store_id, + case + when vcs is null then 'None' + else 'vault credential store' + end as credential_store_type, + coalesce(vcs.name, 'None') as credential_store_name, + coalesce(vcs.description, 'None') as credential_store_description, + coalesce(vcs.namespace, 'None') as credential_store_vault_namespace, + coalesce(vcs.vault_address, 'None') as credential_store_vault_address, + t.public_id as target_id, + case + when tt.type = 'tcp' then 'tcp target' + when tt.type = 'ssh' then 'ssh target' + when tt.type = 'rdp' then 'rdp target' + else 'Unknown' + end as target_type, + coalesce(tt.name, 'None') as target_name, + coalesce(tt.description, 'None') as target_description, + coalesce(tt.default_port, 0) as target_default_port_number, + tt.session_max_seconds as target_session_max_seconds, + tt.session_connection_limit as target_session_connection_limit, + p.public_id as project_id, + coalesce(p.name, 'None') as project_name, + coalesce(p.description, 'None') as project_description, + o.public_id as organization_id, + coalesce(o.name, 'None') as organization_name, + coalesce(o.description, 'None') as organization_description + from session_credential_dynamic as scd + join session as s on scd.session_id = s.public_id + join credential_library as cl on scd.library_id = cl.public_id + join credential_store as cs on cl.store_id = cs.public_id + join target as t on s.target_id = t.public_id + join iam_scope as p on p.public_id = t.project_id and p.type = 'project' + join iam_scope as o on p.parent_id = o.public_id and o.type = 'org' + left join vault_generic_library as vcl on cl.public_id = vcl.public_id + left join vault_ssh_cert_library as vsccl on cl.public_id = vsccl.public_id + left join credential_vault_store as vcs on cs.public_id = vcs.public_id + left join target_all_subtypes as tt on t.public_id = tt.public_id + ) + select session_id, + credential_purpose, + credential_library_id, + credential_library_type, + credential_library_name, + credential_library_description, + credential_library_vault_path, + credential_library_vault_http_method, + credential_library_vault_http_request_body, + credential_library_username, + credential_library_key_type_and_bits, + credential_store_id, + credential_store_type, + credential_store_name, + credential_store_description, + credential_store_vault_namespace, + credential_store_vault_address, + target_id, + target_type, + target_name, + target_description, + target_default_port_number, + target_session_max_seconds, + target_session_connection_limit, + project_id, + project_name, + project_description, + organization_id, + organization_name, + organization_description + from final; + + -- Replaces view defined in 98/02_username_password_domain_vault.up.sql + drop view credential_vault_library_issue_credentials; + create view credential_vault_library_issue_credentials as + with + password_override (library_id, username_attribute, password_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(password_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_username_password_mapping_ovrd + ), + ssh_private_key_override (library_id, username_attribute, private_key_attribute, private_key_passphrase_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(private_key_attribute, wt_to_sentinel('no override')), + nullif(private_key_passphrase_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_ssh_private_key_mapping_ovrd + ), + password_domain_override (library_id, username_attribute, password_attribute, domain_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(password_attribute, wt_to_sentinel('no override')), + nullif(domain_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd + ) + select library.public_id as public_id, + library.store_id as store_id, + library.name as name, + library.description as description, + library.create_time as create_time, + library.update_time as update_time, + library.version as version, + library.vault_path as vault_path, + library.http_method as http_method, + library.http_request_body as http_request_body, + library.credential_type as credential_type, + null as key_type, + null as key_bits, + null as username, + null as ttl, + null as key_id, + null as critical_options, + null as extensions, + store.project_id as project_id, + store.vault_address as vault_address, + store.namespace as namespace, + store.ca_cert as ca_cert, + store.tls_server_name as tls_server_name, + store.tls_skip_verify as tls_skip_verify, + store.worker_filter as worker_filter, + store.ct_token as ct_token, -- encrypted + store.token_hmac as token_hmac, + store.token_status as token_status, + store.token_key_id as token_key_id, + store.client_cert as client_cert, + store.ct_client_key as ct_client_key, -- encrypted + store.client_key_id as client_key_id, + coalesce(upasso.username_attribute, sshpk.username_attribute, pd.username_attribute) + as username_attribute, + coalesce(upasso.password_attribute, pd.password_attribute) + as password_attribute, + pd.domain_attribute as domain_attribute, + sshpk.private_key_attribute as private_key_attribute, + sshpk.private_key_passphrase_attribute as private_key_passphrase_attribute, + 'generic' as cred_lib_type, -- used to switch on + null as additional_valid_principals + from credential_vault_generic_library library + join credential_vault_store_client store + on library.store_id = store.public_id + left join password_override upasso + on library.public_id = upasso.library_id + left join ssh_private_key_override sshpk + on library.public_id = sshpk.library_id + left join password_domain_override pd + on library.public_id = pd.library_id + union + select library.public_id as public_id, + library.store_id as store_id, + library.name as name, + library.description as description, + library.create_time as create_time, + library.update_time as update_time, + library.version as version, + library.vault_path as vault_path, + null as http_method, + null as http_request_body, + library.credential_type as credential_type, + library.key_type as key_type, + library.key_bits as key_bits, + library.username as username, + library.ttl as ttl, + library.key_id as key_id, + library.critical_options as critical_options, + library.extensions as extensions, + store.project_id as project_id, + store.vault_address as vault_address, + store.namespace as namespace, + store.ca_cert as ca_cert, + store.tls_server_name as tls_server_name, + store.tls_skip_verify as tls_skip_verify, + store.worker_filter as worker_filter, + store.ct_token as ct_token, -- encrypted + store.token_hmac as token_hmac, + store.token_status as token_status, + store.token_key_id as token_key_id, + store.client_cert as client_cert, + store.ct_client_key as ct_client_key, -- encrypted + store.client_key_id as client_key_id, + null as username_attribute, + null as password_attribute, + null as domain_attribute, + null as private_key_attribute, + null as private_key_passphrase_attribute, + 'ssh-signed-cert' as cred_lib_type, -- used to switch on + additional_valid_principals as additional_valid_principals + from credential_vault_ssh_cert_library library + join credential_vault_store_client store + on library.store_id = store.public_id; + comment on view credential_vault_library_issue_credentials is + 'credential_vault_library_issue_credentials is a view where each row contains a credential library and the credential library''s data needed to connect to Vault. ' + 'This view should only be used when issuing credentials from a Vault credential library. Each row may contain encrypted data. ' + 'This view should not be used to retrieve data which will be returned external to boundary.'; + + -- Replaces and renames view defined in 98/02_username_password_domain_vault.up.sql. + alter view credential_vault_library_list_lookup + rename to credential_vault_generic_library_list_lookup; + drop view credential_vault_generic_library_list_lookup; + create view credential_vault_generic_library_list_lookup as + with + password_override (library_id, username_attribute, password_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(password_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_username_password_mapping_ovrd + ), + ssh_private_key_override (library_id, username_attribute, private_key_attribute, private_key_passphrase_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(private_key_attribute, wt_to_sentinel('no override')), + nullif(private_key_passphrase_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_ssh_private_key_mapping_ovrd + ), + password_domain_override (library_id, username_attribute, password_attribute, domain_attribute) as ( + select library_id, + nullif(username_attribute, wt_to_sentinel('no override')), + nullif(password_attribute, wt_to_sentinel('no override')), + nullif(domain_attribute, wt_to_sentinel('no override')) + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd + ) + select library.public_id as public_id, + library.store_id as store_id, + library.name as name, + library.description as description, + library.create_time as create_time, + library.update_time as update_time, + library.version as version, + library.vault_path as vault_path, + library.http_method as http_method, + library.http_request_body as http_request_body, + library.credential_type as credential_type, + coalesce(upasso.username_attribute, sshpk.username_attribute, pd.username_attribute) + as username_attribute, + coalesce(upasso.password_attribute, pd.password_attribute) + as password_attribute, + sshpk.private_key_attribute as private_key_attribute, + sshpk.private_key_passphrase_attribute as private_key_passphrase_attribute, + pd.domain_attribute as domain_attribute + from credential_vault_generic_library library + left join password_override upasso + on library.public_id = upasso.library_id + left join ssh_private_key_override sshpk + on library.public_id = sshpk.library_id + left join password_domain_override pd + on library.public_id = pd.library_id; + comment on view credential_vault_generic_library_list_lookup is + 'credential_vault_generic_library_list_lookup is a view where each row contains a Vault generic credential library and any of library''s credential mapping overrides. ' + 'No encrypted data is returned. This view can be used to retrieve data which will be returned external to boundary.'; + + -- Replaces and renames view defined in 71/17_credential_history_views.up.sql. + alter view credential_vault_library_hst_aggregate + rename to credential_vault_generic_library_hst_aggregate; + drop view credential_vault_generic_library_hst_aggregate; + create view credential_vault_generic_library_hst_aggregate as + select + rdc.recording_id, + vl.public_id, + vl.name, + vl.description, + vl.vault_path, + vl.http_method, + vl.http_request_body, + vl.credential_type, + vsh.public_id as store_public_id, + vsh.project_id as store_project_id, + vsh.name as store_name, + vsh.description as store_description, + vsh.vault_address as store_vault_address, + vsh.namespace as store_namespace, + vsh.tls_server_name as store_tls_server_name, + vsh.tls_skip_verify as store_tls_skip_verify, + vsh.worker_filter as store_worker_filter, + string_agg(distinct rdc.credential_purpose, '|') as purposes + from credential_vault_generic_library_hst as vl + left join recording_dynamic_credential as rdc on vl.history_id = rdc.credential_library_hst_id + join credential_vault_store_hst as vsh on rdc.credential_vault_store_hst_id = vsh.history_id + group by vl.history_id, rdc.recording_id, vsh.history_id; + comment on view credential_vault_generic_library_hst_aggregate is + 'credential_vault_generic_library_hst_aggregate contains Vault generic credential library history data along with its store and purpose data.'; + + + -- Renaming is complete. We can now redefine credential_vault_library and + -- rewire all the Vault subtype tables into this redefined table. + + -- credential_vault_store doesn't have a unique constraint on (project_id, + -- public_id) fields. We'll need this to attach a FK to them later. There + -- should be no side-effects from this given that: + -- > public_id is a PK (already globally unique) and, + -- > credential_vault_store is a subtype table of credential_store, which + -- does have a (project_id, public_id) uniqueness constraint. + alter table credential_vault_store + add constraint credential_vault_store_project_id_public_id_uq + unique(project_id, public_id); + + -- This statement defines the basic fields and pulls all the data from + -- credential_library. We can do this as a blanket select * statement because + -- only Vault-subtype credential libraries exist at this point. + -- + -- We want to insert the data before any constraints are set because + -- credential_library has had a few revisions and while we have also updated + -- the data alongside those table revisions, success on an insert with + -- historical data isn't guaranteed. Additionally, we also want to do this + -- before any triggers are put in place. + create table credential_vault_library as + select * from credential_library; + + alter table credential_vault_library + add primary key (public_id), + alter column store_id set not null, + alter column credential_type set not null, + alter column credential_type set default 'unspecified', + add constraint credential_type_enm_fkey + foreign key (credential_type) + references credential_type_enm (name) + on delete restrict + on update cascade, + alter column project_id set not null, + alter column create_time set not null, + alter column update_time set not null, + add constraint credential_library_fkey + foreign key (public_id, store_id, credential_type, project_id) + references credential_library (public_id, store_id, credential_type, project_id) + on delete cascade + on update cascade, + add constraint credential_vault_store_fkey + foreign key (project_id, store_id) + references credential_vault_store (project_id, public_id) + on delete cascade + on update cascade, + add constraint credential_vault_library_project_id_public_id_uq + unique(project_id, public_id), + add constraint credential_vault_library_project_store_public_ids_credtype_uq + unique(project_id, store_id, public_id, credential_type); + comment on table credential_vault_library is + 'credential_vault_library is a base table for Vault credential library ' + 'subtypes and a child table of credential_vault_store. Each row maps 1-to-1 ' + 'to a row in one of the Vault credential library subtype tables.'; + + create trigger immutable_columns before update on credential_vault_library + for each row execute function immutable_columns('public_id', 'store_id', 'project_id', 'credential_type'); + create trigger insert_credential_library_subtype before insert on credential_vault_library + for each row execute procedure insert_credential_library_subtype(); + create trigger delete_credential_library_subtype after delete on credential_vault_library + for each row execute procedure delete_credential_library_subtype(); + create trigger update_credential_library_table_update_time before update on credential_vault_library + for each row execute procedure update_credential_library_table_update_time(); + + create index credential_vault_library_create_time_public_id_idx + on credential_vault_library (create_time desc, public_id desc); + create index credential_vault_library_update_time_public_id_idx + on credential_vault_library (update_time desc, public_id desc); + + create or replace function insert_credential_vault_library_subtype() returns trigger + as $$ + begin + select project_id into new.project_id + from credential_store + where credential_store.public_id = new.store_id; + + insert into credential_vault_library + (public_id, store_id, project_id, credential_type, create_time) + values + (new.public_id, new.store_id, new.project_id, new.credential_type, new.create_time); + return new; + end; + $$ language plpgsql; + comment on function insert_credential_vault_library_subtype() is + 'insert_credential_vault_library_subtype is a before insert trigger ' + 'function that inserts rows from subtype tables into ' + 'credential_vault_library. It must be used on all Vault credential library ' + 'subtype tables.'; + + create function delete_credential_vault_library_subtype() returns trigger + as $$ + begin + delete from credential_vault_library + where public_id = old.public_id; + return null; -- result is ignored since this is an after trigger + end; + $$ language plpgsql; + comment on function delete_credential_vault_library_subtype() is + 'delete_credential_vault_library_subtype is an after delete trigger ' + 'function that deletes rows from credential_vault_library when they''re ' + 'deleted on the subtype tables. It must be used on all Vault credential ' + 'library subtype tables.'; + + create function update_credential_vault_library_table_update_time() returns trigger + as $$ + begin + update credential_vault_library set update_time = now() where public_id = new.public_id; + return new; + end; + $$ language plpgsql; + comment on function update_credential_vault_library_table_update_time() is + 'update_credential_vault_library_table_update_time is a before update ' + 'trigger function that updates the update_time column on ' + 'credential_vault_library. It must be used on all Vault credential library ' + 'subtype tables.'; + + + -- We still have some entities on the Vault subtype tables that reference + -- credential_library when they should now reference credential_vault_library. + alter table credential_vault_generic_library + drop constraint credential_library_fkey, + add constraint credential_vault_library_fkey + foreign key (project_id, store_id, public_id, credential_type) + references credential_vault_library (project_id, store_id, public_id, credential_type) + on delete cascade + on update cascade; + + -- Updates table defined in 63/01_credential_vault_ssh_cert_library.up.sql + alter table credential_vault_ssh_cert_library + drop constraint credential_library_fkey, + add constraint credential_vault_library_fkey + foreign key (project_id, store_id, public_id, credential_type) + references credential_vault_library (project_id, store_id, public_id, credential_type) + on delete cascade + on update cascade; + + drop trigger insert_credential_library_subtype on credential_vault_generic_library; + create trigger insert_credential_vault_library_subtype before insert on credential_vault_generic_library + for each row execute procedure insert_credential_vault_library_subtype(); + + drop trigger delete_credential_library_subtype on credential_vault_generic_library; + create trigger delete_credential_vault_library_subtype after delete on credential_vault_generic_library + for each row execute procedure delete_credential_vault_library_subtype(); + + drop trigger update_credential_library_table_update_time on credential_vault_generic_library; + create trigger update_credential_vault_library_table_update_time before update on credential_vault_generic_library + for each row execute procedure update_credential_vault_library_table_update_time(); + + drop trigger insert_credential_library_subtype on credential_vault_ssh_cert_library; + create trigger insert_credential_vault_library_subtype before insert on credential_vault_ssh_cert_library + for each row execute procedure insert_credential_vault_library_subtype(); + + drop trigger delete_credential_library_subtype on credential_vault_ssh_cert_library; + create trigger delete_credential_vault_library_subtype after delete on credential_vault_ssh_cert_library + for each row execute procedure delete_credential_vault_library_subtype(); + + drop trigger update_credential_library_table_update_time on credential_vault_ssh_cert_library; + create trigger update_credential_vault_library_table_update_time before update on credential_vault_ssh_cert_library + for each row execute procedure update_credential_vault_library_table_update_time(); + + -- Finally, we can correct the restriction in credential_vault_credential. + -- credential_vault_library is now a superset of + -- credential_vault_generic_library, so this shouldn't have side-effects. + -- Updates the table defined in 10/04_vault_credential.up.sql + alter table credential_vault_credential + drop constraint credential_vault_library_fkey, + add constraint credential_vault_library_fkey + foreign key (library_id) + references credential_vault_library (public_id) + on delete set null + on update cascade; +commit; diff --git a/internal/db/schema/migrations/oss/postgres/99/README.md b/internal/db/schema/migrations/oss/postgres/99/README.md new file mode 100644 index 0000000000..6873d04d3a --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/99/README.md @@ -0,0 +1,50 @@ +# Vault Generic Credential Library DB Refactor +Historically, the "Vault generic" credential library was named just "Vault" +credential library. Over the course of Boundary's development, it was renamed to +"Vault generic" to better match its abilities and to conceptually separate it +from other Vault-specific credential libraries, however this nomenclature change +was not applied to database (or domain) entities. This migration applies this +nomenclature change at the database level, renaming all related entities to +match the new "Vault generic" name. + +Currently, these database entities are either named or prefixed with +`credential_vault_library`. This migration changes them to be named or prefixed +with `credential_vault_generic_library`. + +Additionally, `credential_vault_library` takes on a new meaning and is defined +as a new base table that holds information about all *Vault-specific* credential +libraries. `credential_vault_library` is a subtype table of +`credential_library`: + +``` +credential_library |> credential_vault_library |> credential_vault_generic_library + | |> credential_vault_ssh_cred_library + | |> any future Vault-specific credential libraries + | +In the future, we could also have: + |> base table for a non-Vault system's credlibs |> credential library subtype tables +``` + +While the history table for Vault generic credential libraries is renamed to +`credential_vault_generic_library_hst`, the overall history design remains +unchanged. + +This pattern is being established due to the need to differentiate between the +systems that Boundary's credential libraries integrate with, for database +integrity purposes: + +`credential_dynamic` is a base table that represents all renewable/revokable +dynamic credentials. `credential_vault_credential` is a subtype table that +represents renewable/revokable dynamic credentials (Vault leases). Given the +specificity of this design, these leases must be obtained by a Vault credential +library. + +To enforce this, the `library_id` field in `credential_vault_credential` has a +foreign key constraint on `credential_vault_library(public_id)`, meaning only +Vault leases obtained by a Vault generic credential library can ever be inserted +into this table and therefore managed by Boundary. + +With the future introduction of new Vault credential libraries that can also +issue Vault leases, this constraint becomes too restrictive and the design needs +to be extended. By redefining `credential_vault_library` as described above, +this refactor provides the backing for this to be done. diff --git a/internal/db/schema/migrations/oss/postgres_99_01_test.go b/internal/db/schema/migrations/oss/postgres_99_01_test.go new file mode 100644 index 0000000000..e3e80d22da --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres_99_01_test.go @@ -0,0 +1,1131 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package oss_test + +import ( + "database/sql" + "fmt" + "math/rand/v2" + "strconv" + "testing" + "time" + + "github.com/hashicorp/boundary/internal/db/common" + "github.com/hashicorp/boundary/internal/db/schema" + "github.com/hashicorp/boundary/testing/dbtest" + "github.com/hashicorp/go-secure-stdlib/base62" + "github.com/stretchr/testify/require" +) + +// TestVaultCredLibRefactor tests the credential_vault_library refactor. It +// inserts state in the changed tables prior to the refactor migration, executes +// the refactor migration and then asserts that this state is still correct. +// +// For structural tests, see +// sqltest/tests/credential/vault/credential_vault_library_refactor.sql. +// +// For context, see 99/README.md. +func TestVaultCredLibRefactor(t *testing.T) { + t.Parallel() + require := require.New(t) + + c := testVaultCredLibRefactorDbSetupCounts{ + orgs: 2, + projectsPerOrg: 4, + vaultGenericCredLibs: 20, + vaultGenericCredLibsDeleted: 5, + vaultSshCertCredLibs: 20, + vaultSshCertCredLibsDeleted: 5, + } + + dataBeforeMigration, dataAfterMigration := testVaultCredLibRefactorDbSetup(t, c) + require.NotEmpty(dataBeforeMigration) + require.NotEmpty(dataAfterMigration) + + // Validate that `testVaultCredLibRefactorDbSetup` seeded data correctly + // according to the count variables above. + require.Len(dataBeforeMigration.orgs, c.orgs) + require.Len(dataBeforeMigration.projects, c.orgs*c.projectsPerOrg) + require.Len(dataBeforeMigration.credentialStores, c.orgs*c.projectsPerOrg) + require.Len(dataBeforeMigration.credLibBase, (c.orgs*c.projectsPerOrg*c.vaultGenericCredLibs)+(c.orgs*c.projectsPerOrg*c.vaultSshCertCredLibs)) + require.NotEmpty(dataBeforeMigration.credLibHistoryBase) // Some credential libraries have been updated so they'll have more than 1 history entry. + require.Len(dataBeforeMigration.postRefactorVaultCredLibBase, 0) + require.Len(dataBeforeMigration.vaultGenericCredLibs, c.orgs*c.projectsPerOrg*c.vaultGenericCredLibs) + require.Len(dataBeforeMigration.vaultSshCertCredLibs, c.orgs*c.projectsPerOrg*c.vaultSshCertCredLibs) + require.Len(dataBeforeMigration.deletedVaultGenericCredLibs, c.orgs*c.projectsPerOrg*c.vaultGenericCredLibsDeleted) + require.Len(dataBeforeMigration.deletedVaultSshCertCredLibs, c.orgs*c.projectsPerOrg*c.vaultSshCertCredLibsDeleted) + + // Validate migrated data. Given that we asserted the data before migration + // is correctly seeded, we can just assert that post-migration and + // pre-migration elements match. + require.ElementsMatch(dataBeforeMigration.orgs, dataAfterMigration.orgs) + require.ElementsMatch(dataBeforeMigration.projects, dataAfterMigration.projects) + require.ElementsMatch(dataBeforeMigration.credentialStores, dataAfterMigration.credentialStores) + require.ElementsMatch(dataBeforeMigration.credLibBase, dataAfterMigration.credLibBase) + require.ElementsMatch(dataBeforeMigration.credLibHistoryBase, dataAfterMigration.credLibHistoryBase) + require.ElementsMatch(dataBeforeMigration.credLibBase, dataAfterMigration.postRefactorVaultCredLibBase) // We fill new credential_vault_library with data from credential_library. + require.ElementsMatch(dataBeforeMigration.vaultGenericCredLibs, dataAfterMigration.vaultGenericCredLibs) + require.ElementsMatch(dataBeforeMigration.vaultSshCertCredLibs, dataAfterMigration.vaultSshCertCredLibs) + require.ElementsMatch(dataBeforeMigration.deletedVaultGenericCredLibs, dataAfterMigration.deletedVaultGenericCredLibs) + require.ElementsMatch(dataBeforeMigration.deletedVaultSshCertCredLibs, dataAfterMigration.deletedVaultSshCertCredLibs) + + // Finally, check table and view row counts. + require.EqualValues(dataBeforeMigration.rowCounts.credLib, dataAfterMigration.rowCounts.credLib) + require.EqualValues(dataBeforeMigration.rowCounts.credLibHistory, dataAfterMigration.rowCounts.credLibHistory) + require.EqualValues(dataBeforeMigration.rowCounts.credLib, dataAfterMigration.rowCounts.credVaultLibPostRefactor) // We fill new credential_vault_library from credential_library. + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibMappingOvrd, dataAfterMigration.rowCounts.credVaultGenericLibMappingOvrd) + + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLib, dataAfterMigration.rowCounts.credVaultGenericLib) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibHistory, dataAfterMigration.rowCounts.credVaultGenericLibHistory) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibDeleted, dataAfterMigration.rowCounts.credVaultGenericLibDeleted) + + require.EqualValues(dataBeforeMigration.rowCounts.credVaultSshCertLib, dataAfterMigration.rowCounts.credVaultSshCertLib) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultSshCertLibHistory, dataAfterMigration.rowCounts.credVaultSshCertLibHistory) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultSshCertLibDeleted, dataAfterMigration.rowCounts.credVaultSshCertLibDeleted) + + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibMappingOvrdUserPass, dataAfterMigration.rowCounts.credVaultGenericLibMappingOvrdUserPass) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibMappingOvrdUserPassDomain, dataAfterMigration.rowCounts.credVaultGenericLibMappingOvrdUserPassDomain) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibMappingOvrdSshPk, dataAfterMigration.rowCounts.credVaultGenericLibMappingOvrdSshPk) + + require.EqualValues(dataBeforeMigration.rowCounts.credVaultLibIssueCredentials, dataAfterMigration.rowCounts.credVaultLibIssueCredentials) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibListLookup, dataAfterMigration.rowCounts.credVaultGenericLibListLookup) + require.EqualValues(dataBeforeMigration.rowCounts.credVaultGenericLibHistoryAgg, dataAfterMigration.rowCounts.credVaultGenericLibHistoryAgg) + require.EqualValues(dataBeforeMigration.rowCounts.credDimensionSource, dataAfterMigration.rowCounts.credDimensionSource) +} + +// testVaultCredLibRefactorDbSetup sets up a Boundary database running a prior +// migration with credential library data, then migrates to the refactored +// version. Not designed to be called outside of TestVaultCredLibRefactor. +func testVaultCredLibRefactorDbSetup(t testing.TB, counts testVaultCredLibRefactorDbSetupCounts) (beforeMigration, afterMigration dbData) { + require := require.New(t) + + const priorMigration = 98006 + const credlibRefactorMigration = 99001 + + dialect := dbtest.Postgres + c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1)) + require.NoError(err) + t.Cleanup(func() { require.NoError(c()) }) + + db, err := common.SqlOpen(dialect, u) + require.NoError(err) + + // Migrate to the prior migration (before the one we want to test). + m, err := schema.NewManager(t.Context(), schema.Dialect(dialect), db, schema.WithEditions( + schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": priorMigration}), + )) + require.NoError(err) + + _, err = m.ApplyMigrations(t.Context()) + require.NoError(err) + + state, err := m.CurrentState(t.Context()) + require.NoError(err) + require.Equal(&schema.State{ + Initialized: true, + Editions: []schema.EditionState{ + { + Name: "oss", + BinarySchemaVersion: priorMigration, + DatabaseSchemaVersion: priorMigration, + DatabaseSchemaState: schema.Equal, + }, + }, + }, state) + + tx, err := db.BeginTx(t.Context(), &sql.TxOptions{}) + require.NoError(err) + require.NotNil(tx) + + // Queries to seed all the required data. + createOrgScopeQuery := ` + insert into iam_scope + (parent_id, type, public_id, name) + values + ('global', 'org', $1, $2); + ` + createProjectScopeQuery := ` + insert into iam_scope + (parent_id, type, public_id, name) + values + ( $1, 'project', $2, $3); + ` + createCredStoreQuery := ` + insert into credential_vault_store + (public_id, project_id, name, vault_address) + values + ( $1, $2, $3, $4); + ` + createVaultGenericCredLibQuery := ` + insert into credential_vault_library + (public_id, store_id, project_id, name, description, credential_type, vault_path, http_method, http_request_body) + values + ( $1, $2, $3, $4, $5, $6, $7, $8, $9); + ` + updateVaultGenericCredLibQuery := ` + update credential_vault_library + set name = $1, + description = $2, + vault_path = $3 + where public_id = $4; + ` + deleteVaultGenericCredLibQuery := ` + delete from credential_vault_library + where public_id = $1; + ` + createUpMappingOvrdQuery := ` + insert into credential_vault_library_username_password_mapping_override + (library_id, username_attribute, password_attribute) + values + ( $1, $2, $3); + ` + createUpdMappingOvrdQuery := ` + insert into credential_vault_library_username_password_domain_mapping_ovrd + (library_id, username_attribute, password_attribute, domain_attribute) + values + ( $1, $2, $3, $4); + ` + createSshPkMappingOvrdQuery := ` + insert into credential_vault_library_ssh_private_key_mapping_override + (library_id, username_attribute, private_key_attribute, private_key_passphrase_attribute) + values + ( $1, $2, $3, $4); + ` + createVaultSshCertCredLibQuery := ` + insert into credential_vault_ssh_cert_library + (public_id, store_id, project_id, name, description, credential_type, vault_path, username, key_type, key_bits, ttl, key_id, critical_options, extensions, additional_valid_principals) + values + ( $1, $2, $3, $4, $5, 'ssh_certificate', $6, $7, $8, $9, $10, $11, $12, $13, $14); + ` + updateVaultSshCertCredLibQuery := ` + update credential_vault_ssh_cert_library + set name = $1, + description = $2, + vault_path = $3, + username = $4 + where public_id = $5; + ` + deleteVaultSshCertCredLibQuery := ` + delete from credential_vault_ssh_cert_library + where public_id = $1; + ` + + execOk := func(res sql.Result, err error) { + // Exec returned no error. + require.NoError(err) + require.NotNil(res) + + // Exec affected at least 1 row. + ra, err := res.RowsAffected() + require.NoError(err) + require.Greater(ra, int64(0)) + } + + // Create org scopes. + for range counts.orgs { + orgId := fmt.Sprintf("o_%s", base62.MustRandom(10)) + orgName := fmt.Sprintf("Test %q Org Scope", orgId) + execOk(tx.ExecContext(t.Context(), createOrgScopeQuery, orgId, orgName)) + + // For each org scope, create `projectsPerOrgCount` project scopes and a + // Vault credential store. + for range counts.projectsPerOrg { + projectId := fmt.Sprintf("p_%s", base62.MustRandom(10)) + projectName := fmt.Sprintf("Test %q Project Scope", projectId) + execOk(tx.ExecContext(t.Context(), createProjectScopeQuery, orgId, projectId, projectName)) + + credStoreId := fmt.Sprintf("csst_%s", base62.MustRandom(10)) + credStoreName := fmt.Sprintf("Test %q Vault Credential Store", credStoreId) + execOk(tx.ExecContext(t.Context(), createCredStoreQuery, credStoreId, projectId, credStoreName, "http://127.0.0.1:8200")) + + // For each credential store, create `vaultGenericCredLibs` Vault + // generic credential libraries with differing configurations and + // mapping overrides. Add `vaultGenericCredLibsDeleted` to account + // for the ones we have to create to delete. + deletedVaultGenericCredLibs := 0 + for range counts.vaultGenericCredLibs + counts.vaultGenericCredLibsDeleted { + vgCredLibId := fmt.Sprintf("clvlt_%s", base62.MustRandom(10)) + vgCredLibName := fmt.Sprintf("Test %q Vault Generic Credential Library", base62.MustRandom(10)) + + var vgCredType string + switch rand.IntN(4) { + case 0: + vgCredType = "unspecified" + case 1: + vgCredType = "username_password" + case 2: + vgCredType = "username_password_domain" + case 3: + vgCredType = "ssh_private_key" + } + + var vgHttpMethod string + var vgHttpReqBody []byte + switch rand.IntN(2) { + case 0: + vgHttpMethod = "GET" + case 1: + vgHttpMethod = "POST" + vgHttpReqBody = []byte(`{"my_custom_request_body":true, "data": "this_is_some_data"}`) + } + + execOk(tx.ExecContext(t.Context(), createVaultGenericCredLibQuery, + vgCredLibId, credStoreId, projectId, vgCredLibName, vgCredLibName, + vgCredType, "/my/vg/vault/path", vgHttpMethod, vgHttpReqBody, + )) + + var vgMappingOverrideQuery string + vgMappingOverrideArgs := []any{vgCredLibId} + switch vgCredType { + case "unspecified": // No mapping override. + case "username_password": + vgMappingOverrideQuery = createUpMappingOvrdQuery + vgMappingOverrideArgs = append(vgMappingOverrideArgs, "username_ovrd", "password_ovrd") + case "username_password_domain": + vgMappingOverrideQuery = createUpdMappingOvrdQuery + vgMappingOverrideArgs = append(vgMappingOverrideArgs, "username_ovrd", "password_ovrd", "domain_ovrd") + case "ssh_private_key": + vgMappingOverrideQuery = createSshPkMappingOvrdQuery + vgMappingOverrideArgs = append(vgMappingOverrideArgs, "username_ovrd", "ssh_pk_ovrd", "ssh_pk_passphrase_ovrd") + } + if vgMappingOverrideQuery != "" { + execOk(tx.ExecContext(t.Context(), vgMappingOverrideQuery, vgMappingOverrideArgs...)) + } + + // Chance of updating the credential library. + switch rand.IntN(10) { + case 0: + execOk(tx.ExecContext(t.Context(), updateVaultGenericCredLibQuery, "Updated"+vgCredLibName, + "Updated"+vgCredLibName, "/my/updated/vault/path", vgCredLibId)) + } + + if counts.vaultGenericCredLibsDeleted > deletedVaultGenericCredLibs { + execOk(tx.ExecContext(t.Context(), deleteVaultGenericCredLibQuery, vgCredLibId)) + deletedVaultGenericCredLibs++ + } + } + + // For each credential store, create `vaultSshCertCredLibs` Vault + // SSH Certificate credential libraries with different + // configurations. Add `vaultSshCertCredLibsDeleted` to account for + // the ones we have to create to delete. + deletedSshCertCredLibs := 0 + for range counts.vaultSshCertCredLibs + counts.vaultSshCertCredLibsDeleted { + vSshCertCredLibId := fmt.Sprintf("clvsclt_%s", base62.MustRandom(10)) + vSshCertCredLibName := fmt.Sprintf("Test %q Vault SSH Certificate Credential Library", base62.MustRandom(10)) + + var keyType string + var keyBits int + switch rand.IntN(3) { + case 0: + keyType = "ed25519" + keyBits = 0 + case 1: + keyType = "ecdsa" + keyBits = 521 + case 2: + keyType = "rsa" + keyBits = 4096 + } + + var ttl string + switch rand.IntN(2) { + case 0: // No TTL. + case 1: + ttl = strconv.FormatInt(rand.Int64N(65536), 10) + } + + var keyId string + switch rand.IntN(2) { + case 0: // No key id. + case 1: + keyId = "my_key_id" + } + + var criticalOptions []byte + switch rand.IntN(2) { + case 0: // No Critical options. + case 1: + criticalOptions = []byte(`critical_option1=yes, critical_option2=alsoyes, critical_option3=yep`) + } + + var extensions []byte + switch rand.IntN(2) { + case 0: // No extensions. + case 1: + extensions = []byte(`extension1=yes, extension2=alsoyes, extension3=yep`) + } + + var additionalPrincipals string + switch rand.IntN(2) { + case 0: // No additional principals. + case 1: + additionalPrincipals = "principal1, principal2, principal3" + } + + execOk(tx.ExecContext(t.Context(), createVaultSshCertCredLibQuery, + vSshCertCredLibId, credStoreId, projectId, vSshCertCredLibName, + vSshCertCredLibName, "/ssh/sign/cert1", "username", keyType, + keyBits, ttl, keyId, criticalOptions, extensions, additionalPrincipals, + )) + require.NoError(err) + + // Chance of updating credential library. + switch rand.IntN(10) { + case 0: + execOk(tx.ExecContext(t.Context(), updateVaultSshCertCredLibQuery, "Updated"+vSshCertCredLibName, + "Updated"+vSshCertCredLibName, "/ssh/issue/updated_cert1", "updated_username", vSshCertCredLibId)) + } + + if counts.vaultSshCertCredLibsDeleted > deletedSshCertCredLibs { + execOk(tx.ExecContext(t.Context(), deleteVaultSshCertCredLibQuery, vSshCertCredLibId)) + deletedSshCertCredLibs++ + } + } + } + } + err = tx.Commit() + require.NoError(err) + + // Get a snapshot of what the data looks like before the migration. + beforeMigration = testBuildTestVaultCredLibRefactorDbData(t, db, false) + + // Now we're ready for the migration we want to test. + m, err = schema.NewManager(t.Context(), schema.Dialect(dialect), db, schema.WithEditions( + schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": credlibRefactorMigration}), + )) + require.NoError(err) + + _, err = m.ApplyMigrations(t.Context()) + require.NoError(err) + + state, err = m.CurrentState(t.Context()) + require.NoError(err) + require.Equal(&schema.State{ + Initialized: true, + Editions: []schema.EditionState{ + { + Name: "oss", + BinarySchemaVersion: credlibRefactorMigration, + DatabaseSchemaVersion: credlibRefactorMigration, + DatabaseSchemaState: schema.Equal, + }, + }, + }, state) + + // Get a snapshot of the data after the migration. + afterMigration = testBuildTestVaultCredLibRefactorDbData(t, db, true) + + return beforeMigration, afterMigration +} + +// testBuildTestVaultCredLibRefactorDbData will build a 'dbData' object from +// database queries. Accepts a boolean that denotes if any given call is +// post-refactor. 'false' means assume before refactor migration; 'true' means +// assume after refactor migration. This boolean controls table names on various +// queries that retrieve data. +func testBuildTestVaultCredLibRefactorDbData(t testing.TB, db *sql.DB, afterRefactor bool) dbData { + require := require.New(t) + + queryContext := func(tx *sql.Tx, query string, callbackFn func(scanFn func(dest ...any) error)) { + rows, err := tx.QueryContext(t.Context(), query) + require.NoError(err) + require.NotNil(rows) + + for rows.Next() { + callbackFn(rows.Scan) + } + require.NoError(rows.Err()) + } + + data := dbData{ + orgs: make([]orgProj, 0), + projects: make([]orgProj, 0), + credentialStores: make([]vaultCredStore, 0), + credLibBase: make([]credLibBase, 0), + credLibHistoryBase: make([]credLibHistoryBase, 0), + postRefactorVaultCredLibBase: make([]credLibBase, 0), + vaultGenericCredLibs: make([]vaultGenericCredLib, 0), + vaultSshCertCredLibs: make([]vaultSshCertCredLib, 0), + deletedVaultGenericCredLibs: make([]credLibDeleted, 0), + deletedVaultSshCertCredLibs: make([]credLibDeleted, 0), + rowCounts: rowCounts{}, + } + + tx, err := db.BeginTx(t.Context(), &sql.TxOptions{}) + require.NoError(err) + require.NotNil(tx) + defer func() { _ = tx.Rollback() }() + + // Get org and project scopes. + queryContext(tx, "select * from iam_scope", func(scanFn func(dest ...any) error) { + var publicId, name, typ, description, parentId, primaryAuthMethodId *string + var createTime, updateTime *time.Time + var version *int + require.NoError(scanFn(&publicId, &createTime, &updateTime, &name, + &typ, &description, &parentId, &version, &primaryAuthMethodId), + ) + + op := orgProj{ + publicId: testDeref(t, publicId), + name: testDeref(t, name), + description: testDeref(t, description), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + typ: testDeref(t, typ), + parentId: testDeref(t, parentId), + version: testDeref(t, version), + } + switch op.typ { + case "global": + case "org": + data.orgs = append(data.orgs, op) + case "project": + data.projects = append(data.projects, op) + default: + require.Failf("failed to get org/project scopes", "unknown scope type %s", op.typ) + } + }) + + // Get credential stores. + queryContext(tx, "select * from credential_vault_store", func(scanFn func(dest ...any) error) { + var publicId, projectId, name, description, vaultAddr, namespace, + tlsServerName, workerFilter *string + var createTime, updateTime, deleteTime *time.Time + var version *int + var caCert *[]byte + var tlsSkipVerify *bool + + require.NoError(scanFn(&publicId, &projectId, &name, &description, + &createTime, &updateTime, &deleteTime, &version, &vaultAddr, &namespace, + &caCert, &tlsServerName, &tlsSkipVerify, &workerFilter), + ) + + data.credentialStores = append(data.credentialStores, vaultCredStore{ + publicId: testDeref(t, publicId), + projectId: testDeref(t, projectId), + name: testDeref(t, name), + description: testDeref(t, description), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + deleteTime: testDeref(t, deleteTime), + version: testDeref(t, version), + vaultAddr: testDeref(t, vaultAddr), + namespace: testDeref(t, namespace), + caCert: testDeref(t, caCert), + tlsServerName: testDeref(t, tlsServerName), + tlsSkipVerify: testDeref(t, tlsSkipVerify), + workerFilter: testDeref(t, workerFilter), + }) + }) + + // Get credential library base table. + queryContext(tx, "select * from credential_library", func(scanFn func(dest ...any) error) { + var publicId, storeId, credType, projectId *string + var createTime, updateTime *time.Time + require.NoError(scanFn(&publicId, &storeId, &credType, &projectId, &createTime, &updateTime)) + + data.credLibBase = append(data.credLibBase, credLibBase{ + publicId: testDeref(t, publicId), + storeId: testDeref(t, storeId), + credType: testDeref(t, credType), + projectId: testDeref(t, projectId), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + }) + }) + + // Get credential library base table if we're post-refactor. + if afterRefactor { + queryContext(tx, "select * from credential_vault_library", func(scanFn func(dest ...any) error) { + var publicId, storeId, credType, projectId *string + var createTime, updateTime *time.Time + require.NoError(scanFn(&publicId, &storeId, &credType, &projectId, &createTime, &updateTime)) + + data.postRefactorVaultCredLibBase = append(data.postRefactorVaultCredLibBase, credLibBase{ + publicId: testDeref(t, publicId), + storeId: testDeref(t, storeId), + credType: testDeref(t, credType), + projectId: testDeref(t, projectId), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + }) + }) + } + + // Get credential library history base table. + queryContext(tx, "select * from credential_library_history_base", func(scanFn func(dest ...any) error) { + var historyId *string + require.NoError(scanFn(&historyId)) + data.credLibHistoryBase = append(data.credLibHistoryBase, credLibHistoryBase{testDeref(t, historyId)}) + }) + + // Get Vault generic credential libraries. + vaultGenericCredLibTableName := "credential_vault_library" + if afterRefactor { + vaultGenericCredLibTableName = "credential_vault_generic_library" + } + queryContext(tx, fmt.Sprintf("select * from %s", vaultGenericCredLibTableName), func(scanFn func(dest ...any) error) { + var publicId, storeId, name, description, vaultPath, httpMethod, + credType, projectId *string + var createTime, updateTime *time.Time + var version *int + var httpReqBody *[]byte + + require.NoError(scanFn(&publicId, &storeId, &name, &description, + &createTime, &updateTime, &version, &vaultPath, &httpMethod, + &httpReqBody, &credType, &projectId), + ) + + data.vaultGenericCredLibs = append(data.vaultGenericCredLibs, vaultGenericCredLib{ + publicId: testDeref(t, publicId), + storeId: testDeref(t, storeId), + name: testDeref(t, name), + description: testDeref(t, description), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + version: testDeref(t, version), + vaultPath: testDeref(t, vaultPath), + httpMethod: testDeref(t, httpMethod), + httpReqBody: testDeref(t, httpReqBody), + credType: testDeref(t, credType), + projectId: testDeref(t, projectId), + + mappingOverride: vaultGenericCredLibMappingOvrd{}, // Fetch below. + history: make([]vaultGenericCredLibHistory, 0), // Fetch below. + }) + }) + + // Get mapping overrides for Vault generic credential libraries. + upMappingOvrdTableName := "credential_vault_library_username_password_mapping_override" + updMappingOvrdTableName := "credential_vault_library_username_password_domain_mapping_ovrd" + sshPkMappingOvrdTableName := "credential_vault_library_ssh_private_key_mapping_override" + if afterRefactor { + upMappingOvrdTableName = "credential_vault_generic_library_username_password_mapping_ovrd" + updMappingOvrdTableName = "credential_vault_generic_library_usern_pass_domain_mapping_ovrd" + sshPkMappingOvrdTableName = "credential_vault_generic_library_ssh_private_key_mapping_ovrd" + } + for _, cl := range data.vaultGenericCredLibs { + queryFmt := "select * from %s where library_id = '%s'" + getMappingOvrd := false + switch cl.credType { + case "unspecified": + case "username_password": + queryFmt = fmt.Sprintf(queryFmt, upMappingOvrdTableName, cl.publicId) + getMappingOvrd = true + case "username_password_domain": + queryFmt = fmt.Sprintf(queryFmt, updMappingOvrdTableName, cl.publicId) + getMappingOvrd = true + case "ssh_private_key": + queryFmt = fmt.Sprintf(queryFmt, sshPkMappingOvrdTableName, cl.publicId) + getMappingOvrd = true + default: + require.Failf("failed to get vault generic mapping overrides", "unknown credential type %s", cl.credType) + } + if getMappingOvrd { + queryContext(tx, queryFmt, func(scanFn func(dest ...any) error) { + var libraryId, usernameAttr, passwordAttr, domainAttr, pkAttr, + pkPassphraseAttr *string + + switch cl.credType { + case "username_password": + require.NoError(scanFn(&libraryId, &usernameAttr, &passwordAttr)) + case "username_password_domain": + require.NoError(scanFn(&libraryId, &usernameAttr, &passwordAttr, &domainAttr)) + case "ssh_private_key": + require.NoError(scanFn(&libraryId, &usernameAttr, &pkAttr, &pkPassphraseAttr)) + } + + cl.mappingOverride = vaultGenericCredLibMappingOvrd{ + libraryId: testDeref(t, libraryId), + usernameAttr: testDeref(t, usernameAttr), + passwordAttr: testDeref(t, passwordAttr), + domainAttr: testDeref(t, domainAttr), + pkAttr: testDeref(t, pkAttr), + pkPassphraseAttr: testDeref(t, pkPassphraseAttr), + } + }) + } + } + + // Get history for Vault generic credential libraries. + for _, cl := range data.vaultGenericCredLibs { + hstTableName := "credential_vault_library_hst" + if afterRefactor { + hstTableName = "credential_vault_generic_library_hst" + } + + query := fmt.Sprintf("select * from %s where public_id = '%s'", hstTableName, cl.publicId) + queryContext(tx, query, func(scanFn func(dest ...any) error) { + var publicId, name, description, projectId, storeId, vaultPath, + httpMethod, credType, historyId, validRange *string + var httpReqBody *[]byte + + require.NoError(scanFn(&publicId, &name, &description, &projectId, + &storeId, &vaultPath, &httpMethod, &httpReqBody, &credType, + &historyId, &validRange), + ) + + cl.history = append(cl.history, vaultGenericCredLibHistory{ + historyId: testDeref(t, historyId), + validRange: testDeref(t, validRange), + cl: vaultGenericCredLib{ + publicId: testDeref(t, publicId), + name: testDeref(t, name), + description: testDeref(t, description), + projectId: testDeref(t, projectId), + storeId: testDeref(t, storeId), + vaultPath: testDeref(t, vaultPath), + httpMethod: testDeref(t, httpMethod), + httpReqBody: testDeref(t, httpReqBody), + credType: testDeref(t, credType), + }, + }) + }) + } + + // Get Vault SSH certificate credential libraries. + queryContext(tx, "select * from credential_vault_ssh_cert_library", func(scanFn func(dest ...any) error) { + var publicId, storeId, name, description, vaultPath, username, keyType, + ttl, keyId, credType, projectId, additionalPrincipals *string + var createTime, updateTime *time.Time + var version, keyBits *int + var criticalOptions, extensions *[]byte + + require.NoError(scanFn(&publicId, &storeId, &name, &description, + &createTime, &updateTime, &version, &vaultPath, &username, &keyType, + &keyBits, &ttl, &keyId, &criticalOptions, &extensions, &credType, + &projectId, &additionalPrincipals), + ) + + data.vaultSshCertCredLibs = append(data.vaultSshCertCredLibs, vaultSshCertCredLib{ + publicId: testDeref(t, publicId), + storeId: testDeref(t, storeId), + name: testDeref(t, name), + description: testDeref(t, description), + createTime: testDeref(t, createTime), + updateTime: testDeref(t, updateTime), + version: testDeref(t, version), + vaultPath: testDeref(t, vaultPath), + username: testDeref(t, username), + keyType: testDeref(t, keyType), + keyBits: testDeref(t, keyBits), + ttl: testDeref(t, ttl), + keyId: testDeref(t, keyId), + criticalOptions: testDeref(t, criticalOptions), + extensions: testDeref(t, extensions), + credType: testDeref(t, credType), + projectId: testDeref(t, projectId), + additionalValidPrincipals: testDeref(t, additionalPrincipals), + + history: make([]vaultSshCertCredLibHistory, 0), // Fetch below. + }) + }) + + // Get history for Vault SSH certificate credential libraries. + for _, cl := range data.vaultSshCertCredLibs { + query := fmt.Sprintf("select * from credential_vault_ssh_cert_library_hst where public_id = '%s'", cl.publicId) + queryContext(tx, query, func(scanFn func(dest ...any) error) { + var publicId, storeId, name, description, vaultPath, username, keyType, + ttl, credType, projectId, historyId, validRange *string + var keyBits *int + var criticalOptions, extensions *[]byte + + require.NoError(scanFn(&publicId, &name, &description, &projectId, + &storeId, &vaultPath, &username, &keyType, &keyBits, &ttl, + &criticalOptions, &extensions, &credType, &historyId, &validRange), + ) + + cl.history = append(cl.history, vaultSshCertCredLibHistory{ + historyId: *historyId, + validRange: *validRange, + cl: vaultSshCertCredLib{ + publicId: testDeref(t, publicId), + name: testDeref(t, name), + description: testDeref(t, description), + projectId: testDeref(t, projectId), + storeId: testDeref(t, storeId), + vaultPath: testDeref(t, vaultPath), + username: testDeref(t, username), + keyType: testDeref(t, keyType), + keyBits: testDeref(t, keyBits), + ttl: testDeref(t, ttl), + criticalOptions: testDeref(t, criticalOptions), + extensions: testDeref(t, extensions), + credType: testDeref(t, credType), + }, + }) + }) + } + + // Get all deleted vault credential libraries. + vaultGenericCredLibDeletedTableName := "credential_vault_library_deleted" + if afterRefactor { + vaultGenericCredLibDeletedTableName = "credential_vault_generic_library_deleted" + } + vaultSshCertCredLibDeletedTableName := "credential_vault_ssh_cert_library_deleted" + deletedTables := []string{vaultGenericCredLibDeletedTableName, vaultSshCertCredLibDeletedTableName} + for _, dt := range deletedTables { + queryContext(tx, fmt.Sprintf("select * from %s", dt), func(scanFn func(dest ...any) error) { + var publicId *string + var deleteTime *time.Time + + require.NoError(scanFn(&publicId, &deleteTime)) + + cld := credLibDeleted{ + publicId: testDeref(t, publicId), + deleteTime: testDeref(t, deleteTime), + } + switch dt { + case vaultGenericCredLibDeletedTableName: + data.deletedVaultGenericCredLibs = append(data.deletedVaultGenericCredLibs, cld) + case vaultSshCertCredLibDeletedTableName: + data.deletedVaultSshCertCredLibs = append(data.deletedVaultSshCertCredLibs, cld) + } + }) + } + + // Get row counts. + var rowCountQuery string + if !afterRefactor { + rowCountQuery = ` + select + ( select count(*) from credential_library ), + ( select count(*) from credential_library_history_base ), + ( select count(*) from credential_vault_library_mapping_override ), + + ( select count(*) from credential_vault_library ), + ( select count(*) from credential_vault_library_hst ), + ( select count(*) from credential_vault_library_deleted ), + + ( select count(*) from credential_vault_ssh_cert_library ), + ( select count(*) from credential_vault_ssh_cert_library_hst ), + ( select count(*) from credential_vault_ssh_cert_library_deleted ), + + ( select count(*) from credential_vault_library_username_password_mapping_override ), + ( select count(*) from credential_vault_library_username_password_domain_mapping_ovrd ), + ( select count(*) from credential_vault_library_ssh_private_key_mapping_override ), + + ( select count(*) from credential_vault_library_issue_credentials ), + ( select count(*) from credential_vault_library_list_lookup ), + ( select count(*) from credential_vault_library_hst_aggregate ), + ( select count(*) from whx_credential_dimension_source ); + ` + } else { + rowCountQuery = ` + select + ( select count(*) from credential_library ), + ( select count(*) from credential_library_history_base ), + ( select count(*) from credential_vault_generic_library_mapping_override ), + ( select count(*) from credential_vault_library ), + + ( select count(*) from credential_vault_generic_library ), + ( select count(*) from credential_vault_generic_library_hst ), + ( select count(*) from credential_vault_generic_library_deleted ), + + ( select count(*) from credential_vault_ssh_cert_library ), + ( select count(*) from credential_vault_ssh_cert_library_hst ), + ( select count(*) from credential_vault_ssh_cert_library_deleted ), + + ( select count(*) from credential_vault_generic_library_username_password_mapping_ovrd ), + ( select count(*) from credential_vault_generic_library_usern_pass_domain_mapping_ovrd ), + ( select count(*) from credential_vault_generic_library_ssh_private_key_mapping_ovrd ), + + ( select count(*) from credential_vault_library_issue_credentials ), + ( select count(*) from credential_vault_generic_library_list_lookup ), + ( select count(*) from credential_vault_generic_library_hst_aggregate ), + ( select count(*) from whx_credential_dimension_source ); + ` + } + queryContext(tx, rowCountQuery, func(scanFn func(dest ...any) error) { + var cl, clHistBase, clVaultBasePostRefactorOnly, clVaultGenericMappingOvrd, + clVaultGeneric, clVaultGenericHist, clVaultGenericDel, clVaultSshCert, + clVaultSshCertHist, clVaultSshCertDel, clVaultGenericUpMappingOvrd, + clVaultGenericUpdMappingOvrd, clVaultGenericSshPkMappingOverd, + clVaultLibIssueCreds, clVaultGenericListLookup, clVaultGenericHistAgg, credDimensionSource *int64 + + if !afterRefactor { + require.NoError(scanFn(&cl, &clHistBase, &clVaultGenericMappingOvrd, + &clVaultGeneric, &clVaultGenericHist, &clVaultGenericDel, + &clVaultSshCert, &clVaultSshCertHist, &clVaultSshCertDel, + &clVaultGenericUpMappingOvrd, &clVaultGenericUpdMappingOvrd, &clVaultGenericSshPkMappingOverd, + &clVaultLibIssueCreds, &clVaultGenericListLookup, &clVaultGenericHistAgg, &credDimensionSource), + ) + } else { + require.NoError(scanFn(&cl, &clHistBase, &clVaultGenericMappingOvrd, &clVaultBasePostRefactorOnly, + &clVaultGeneric, &clVaultGenericHist, &clVaultGenericDel, + &clVaultSshCert, &clVaultSshCertHist, &clVaultSshCertDel, + &clVaultGenericUpMappingOvrd, &clVaultGenericUpdMappingOvrd, &clVaultGenericSshPkMappingOverd, + &clVaultLibIssueCreds, &clVaultGenericListLookup, &clVaultGenericHistAgg, &credDimensionSource), + ) + } + + data.rowCounts = rowCounts{ + credLib: testDeref(t, cl), + credLibHistory: testDeref(t, clHistBase), + credVaultLibPostRefactor: testDeref(t, clVaultBasePostRefactorOnly), + credVaultGenericLibMappingOvrd: testDeref(t, clVaultGenericMappingOvrd), + credVaultGenericLib: testDeref(t, clVaultGeneric), + credVaultGenericLibHistory: testDeref(t, clVaultGenericHist), + credVaultGenericLibDeleted: testDeref(t, clVaultGenericDel), + credVaultSshCertLib: testDeref(t, clVaultSshCert), + credVaultSshCertLibHistory: testDeref(t, clVaultSshCertHist), + credVaultSshCertLibDeleted: testDeref(t, clVaultSshCertDel), + credVaultGenericLibMappingOvrdUserPass: testDeref(t, clVaultGenericUpMappingOvrd), + credVaultGenericLibMappingOvrdUserPassDomain: testDeref(t, clVaultGenericUpdMappingOvrd), + credVaultGenericLibMappingOvrdSshPk: testDeref(t, clVaultGenericSshPkMappingOverd), + credVaultLibIssueCredentials: testDeref(t, clVaultLibIssueCreds), + credVaultGenericLibListLookup: testDeref(t, clVaultGenericListLookup), + credVaultGenericLibHistoryAgg: testDeref(t, clVaultGenericHistAgg), + credDimensionSource: testDeref(t, credDimensionSource), + } + }) + + return data +} + +// testDeref is a generic function that dereferences a pointer type, +// safeguarding against a nil pointer dereference. If the input pointer is nil, +// it returns the zero-value for the input type. +func testDeref[T any](_ testing.TB, in *T) T { + if in == nil { + return *new(T) + } + return *in +} + +// dbData is the aggregation of all the data that +// testBuildTestVaultCredLibRefactorDbData gets together. Not designed to be +// used outside of TestVaultCredLibRefactor. +type dbData struct { + orgs []orgProj // From iam_scope. + projects []orgProj // From iam_scope. + + credentialStores []vaultCredStore // From credential_vault_store. + + credLibBase []credLibBase // From credential_library. + credLibHistoryBase []credLibHistoryBase // From credential_library_history_base. + postRefactorVaultCredLibBase []credLibBase // From credential_vault_library (after refactor only). + + vaultGenericCredLibs []vaultGenericCredLib // From credential_vault_library (pre-refactor) or credential_vault_generic_library. + vaultSshCertCredLibs []vaultSshCertCredLib // From credential_vault_ssh_cert_library. + + deletedVaultGenericCredLibs []credLibDeleted // From credential_vault_library_deleted (pre-refactor) or credential_vault_generic_library_deleted. + deletedVaultSshCertCredLibs []credLibDeleted // From credential_vault_ssh_cert_library_deleted. + + rowCounts rowCounts +} + +// orgProj holds database data about a org/project scope. Not designed to be +// used outside of testBuildTestVaultCredLibRefactorDbData. +type orgProj struct { + publicId string + name string + description string + createTime time.Time + updateTime time.Time + typ string + parentId string + version int +} + +// credLibBase holds database data about a credential library. +// Not designed to be used outside of testBuildTestVaultCredLibRefactorDbData. +type credLibBase struct { + publicId string + storeId string + credType string + projectId string + createTime time.Time + updateTime time.Time +} + +// credLibHistoryBase holds historical data about a credential library. Not +// designed to be used outside of testBuildTestVaultCredLibRefactorDbData. +type credLibHistoryBase struct { + historyId string +} + +// credLibDeleted holds database data about a deleted credential library. Not +// designed to be used outside of testBuildTestVaultCredLibRefactorDbData. +type credLibDeleted struct { + publicId string + deleteTime time.Time +} + +// vaultCredStore holds database data about a Vault credential store. Not +// designed to be used outside of testBuildTestVaultCredLibRefactorDbData. +type vaultCredStore struct { + publicId string + projectId string + name string + description string + createTime time.Time + updateTime time.Time + deleteTime time.Time + version int + vaultAddr string + namespace string + caCert []byte + tlsServerName string + tlsSkipVerify bool + workerFilter string +} + +// vaultGenericCredLib holds database data about a Vault generic credential +// library. Not designed to be used outside of +// testBuildTestVaultCredLibRefactorDbData. +type vaultGenericCredLib struct { + publicId string + storeId string + name string + description string + createTime time.Time + updateTime time.Time + version int + vaultPath string + httpMethod string + httpReqBody []byte + credType string + projectId string + + mappingOverride vaultGenericCredLibMappingOvrd + history []vaultGenericCredLibHistory +} +type vaultGenericCredLibHistory struct { + cl vaultGenericCredLib + historyId string + validRange string +} + +// vaultSshCertCredLib holds database data about a Vault SSH certificate +// credential library. Not designed to be used outside of +// testBuildTestVaultCredLibRefactorDbData. +type vaultSshCertCredLib struct { + publicId string + storeId string + name string + description string + createTime time.Time + updateTime time.Time + version int + vaultPath string + username string + keyType string + keyBits int + ttl string + keyId string + criticalOptions []byte + extensions []byte + credType string + projectId string + additionalValidPrincipals string + + history []vaultSshCertCredLibHistory +} +type vaultSshCertCredLibHistory struct { + cl vaultSshCertCredLib + historyId string + validRange string +} + +// vaultGenericCredLibMappingOvrd holds database data about a Vault generic +// credential library's mapping override. Not designed to be used outside of +// testBuildTestVaultCredLibRefactorDbData. +type vaultGenericCredLibMappingOvrd struct { + libraryId string + usernameAttr string + passwordAttr string + domainAttr string + pkAttr string + pkPassphraseAttr string +} + +// rowCounts holds row count information for various database tables and views. +// Not designed to be used outside of testBuildTestVaultCredLibRefactorDbData. +type rowCounts struct { + // credential_library + credLib int64 + // credential_library_history_base + credLibHistory int64 + // credential_vault_library (post-refactor meaning only) + credVaultLibPostRefactor int64 + // credential_vault_library_mapping_override (pre-refactor) or + // credential_vault_generic_library_mapping_override + credVaultGenericLibMappingOvrd int64 + + // credential_vault_library (pre-refactor) or + // credential_vault_generic_library + credVaultGenericLib int64 + // credential_vault_library_hst (pre-refactor) or + // credential_vault_generic_library_hst + credVaultGenericLibHistory int64 + // credential_vault_library_deleted (pre-refactor) or + // credential_vault_generic_library_deleted + credVaultGenericLibDeleted int64 + + // credential_vault_ssh_cert_library + credVaultSshCertLib int64 + // credential_vault_ssh_cert_library_hst + credVaultSshCertLibHistory int64 + // credential_vault_ssh_cert_library_deleted + credVaultSshCertLibDeleted int64 + + // credential_vault_library_username_password_mapping_override + // (pre-refactor) or + // credential_vault_generic_library_username_password_mapping_ovrd + credVaultGenericLibMappingOvrdUserPass int64 + // credential_vault_library_username_password_domain_mapping_ovrd + // (pre-refactor) or + // credential_vault_generic_library_usern_pass_domain_mapping_ovrd + credVaultGenericLibMappingOvrdUserPassDomain int64 + // credential_vault_library_ssh_private_key_mapping_override (pre-refactor) + // or credential_vault_generic_library_ssh_private_key_mapping_ovrd + credVaultGenericLibMappingOvrdSshPk int64 + + // credential_vault_library_issue_credentials + credVaultLibIssueCredentials int64 + + // credential_vault_library_list_lookup (pre-refactor), or + // credential_vault_generic_library_list_lookup + credVaultGenericLibListLookup int64 + + // credential_vault_library_hst_aggregate (pre-refactor), or + // credential_vault_generic_library_hst_aggregate + credVaultGenericLibHistoryAgg int64 + + // whx_credential_dimension_source + credDimensionSource int64 +} + +// testVaultCredLibRefactorDbSetupCounts is an input to +// testVaultCredLibRefactorDbSetup that controls the number of +// orgs/projects/credential libraries to create. +type testVaultCredLibRefactorDbSetupCounts struct { + // orgs is the number of org scopes to create. + orgs int + + // projectsPerOrg is the number of project scopes to create per org. + projectsPerOrg int + + // vaultGenericCredLibs is the number of Vault generic credential + // libraries to create per project. + vaultGenericCredLibs int + + // vaultGenericCredLibsDeleted is the number of Vault generic credential + // libraries to delete per project. Note that we create new credential + // libraries for the purposes of deletion so this doesn't affect + // vaultGenericCredLibs. + vaultGenericCredLibsDeleted int + + // vaultSshCertCredLibs is the number of Vault SSH Certificate + // credential libraries to create per project. + vaultSshCertCredLibs int + + // vaultSshCertCredLibsDeleted is the number of Vault SSH certificate + // credential libraries to delete per project. Note that we create new + // credential libraries for the purposes of deletion so this doesn't affect + // vaultSshCertCredLibs. + vaultSshCertCredLibsDeleted int +} diff --git a/internal/db/sqltest/initdb.d/01_colors_persona.sql b/internal/db/sqltest/initdb.d/01_colors_persona.sql index f38d9650ed..f792a10e46 100644 --- a/internal/db/sqltest/initdb.d/01_colors_persona.sql +++ b/internal/db/sqltest/initdb.d/01_colors_persona.sql @@ -479,7 +479,7 @@ begin; ('p____rcolors', 'cvs__rcolors', 'red vault store', 'Some', 'https://red.vault.color', 'red'), ('p____gcolors', 'cvs__gcolors', 'green vault store', 'Maybe', 'https://green.vault.color', 'green'); - insert into credential_vault_library + insert into credential_vault_generic_library (store_id, public_id, name, description, vault_path, http_method) values ('cvs__bcolors', 'cvl_______b1', 'blue vault library', 'None', '/secrets', 'GET'), diff --git a/internal/db/sqltest/initdb.d/03_widgets_persona.sql b/internal/db/sqltest/initdb.d/03_widgets_persona.sql index 01b63839d9..58045eb2f2 100644 --- a/internal/db/sqltest/initdb.d/03_widgets_persona.sql +++ b/internal/db/sqltest/initdb.d/03_widgets_persona.sql @@ -388,7 +388,7 @@ begin; values ('vs_______wvs', 'kdkv___widget', 'current', 'hmac-value', 'token-value', now(), now() + interval '1 hour'); - insert into credential_vault_library + insert into credential_vault_generic_library (store_id, public_id, name, description, vault_path, http_method, credential_type) values ('vs_______wvs', 'vl______wvl1', 'widget vault library', 'None', '/secrets', 'GET', 'unspecified'), @@ -413,82 +413,82 @@ begin; ('vs_______wvs', 'vl______wvl20', 'widget vault kv eighteen', 'None', '/secrets/kv/eighteen', 'GET', 'username_password_domain'), ('vs_______wvs', 'vl______wvl21', 'widget vault kv nineteen', 'None', '/secrets/kv/nineteen', 'GET', 'username_password_domain'); - insert into credential_vault_library_username_password_mapping_override + insert into credential_vault_generic_library_username_password_mapping_ovrd (library_id) values ('vl______wvl4'); - insert into credential_vault_library_username_password_mapping_override + insert into credential_vault_generic_library_username_password_mapping_ovrd (library_id, username_attribute) values ('vl______wvl5', 'my_username'); - insert into credential_vault_library_username_password_mapping_override + insert into credential_vault_generic_library_username_password_mapping_ovrd (library_id, password_attribute) values ('vl______wvl6', 'my_password'); - insert into credential_vault_library_username_password_mapping_override + insert into credential_vault_generic_library_username_password_mapping_ovrd (library_id, username_attribute, password_attribute) values ('vl______wvl7', 'my_username', 'my_password'); - insert into credential_vault_library_ssh_private_key_mapping_override + insert into credential_vault_generic_library_ssh_private_key_mapping_ovrd (library_id) values ('vl______wvl9'); - insert into credential_vault_library_ssh_private_key_mapping_override + insert into credential_vault_generic_library_ssh_private_key_mapping_ovrd (library_id, username_attribute) values ('vl______wvl10', 'my_username'); - insert into credential_vault_library_ssh_private_key_mapping_override + insert into credential_vault_generic_library_ssh_private_key_mapping_ovrd (library_id, private_key_attribute) values ('vl______wvl11', 'my_private_key'); - insert into credential_vault_library_ssh_private_key_mapping_override + insert into credential_vault_generic_library_ssh_private_key_mapping_ovrd (library_id, username_attribute, private_key_attribute, private_key_passphrase_attribute) values ('vl______wvl12', 'my_username', 'my_private_key', 'my_passphrase'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id) values ('vl______wvl13'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, username_attribute, password_attribute, domain_attribute) values ('vl______wvl14', 'my_username', 'my_password', 'my_domain'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, username_attribute, domain_attribute) values ('vl______wvl15', 'my_username', 'my_domain'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, password_attribute, domain_attribute) values ('vl______wvl16', 'my_password', 'my_domain'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, username_attribute, password_attribute) values ('vl______wvl17', 'my_username', 'my_password'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, username_attribute) values ('vl______wvl18', 'my_username'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, password_attribute) values ('vl______wvl19', 'my_password'); - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id, domain_attribute) values ('vl______wvl20', 'my_domain'); diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library.sql index ae78da4397..5d04db1f8f 100644 --- a/internal/db/sqltest/tests/credential/vault/credential_vault_library.sql +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library.sql @@ -11,31 +11,31 @@ begin; select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials'); -- validate the setup data - select is(count(*), 1::bigint) from credential_vault_library where public_id = 'vl______wvl1' and credential_type = 'unspecified'; + select is(count(*), 1::bigint) from credential_vault_generic_library where public_id = 'vl______wvl1' and credential_type = 'unspecified'; select is(count(*), 1::bigint) from credential_library where public_id = 'vl______wvl1' and credential_type = 'unspecified'; - select is(count(*), 1::bigint) from credential_vault_library where public_id = 'vl______wvl3' and credential_type = 'username_password'; + select is(count(*), 1::bigint) from credential_vault_generic_library where public_id = 'vl______wvl3' and credential_type = 'username_password'; select is(count(*), 1::bigint) from credential_library where public_id = 'vl______wvl3' and credential_type = 'username_password'; -- validate the insert triggers prepare insert_vault_library as - insert into credential_vault_library + insert into credential_vault_generic_library (store_id, public_id, vault_path, http_method, credential_type) values ('vs_______wvs', 'vl_______tt1', '/secrets/kv', 'GET', 'username_password'); select lives_ok('insert_vault_library'); - select is(count(*), 1::bigint) from credential_vault_library where public_id = 'vl_______tt1' and credential_type = 'username_password'; + select is(count(*), 1::bigint) from credential_vault_generic_library where public_id = 'vl_______tt1' and credential_type = 'username_password'; select is(count(*), 1::bigint) from credential_library where public_id = 'vl_______tt1' and credential_type = 'username_password'; -- validate the delete triggers prepare delete_vault_library as delete - from credential_vault_library + from credential_vault_generic_library where public_id = 'vl_______tt1'; select lives_ok('delete_vault_library'); - select is(count(*), 0::bigint) from credential_vault_library where public_id = 'vl_______tt1'; + select is(count(*), 0::bigint) from credential_vault_generic_library where public_id = 'vl_______tt1'; select is(count(*), 0::bigint) from credential_library where public_id = 'vl_______tt1'; select * from finish(); diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library_issue_credentials.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library_issue_credentials.sql index 5248a335c8..7af2f8adda 100644 --- a/internal/db/sqltest/tests/credential/vault/credential_vault_library_issue_credentials.sql +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library_issue_credentials.sql @@ -13,19 +13,19 @@ begin; select is(count(*), 1::bigint) from credential_vault_store where public_id = 'vs_______wvs'; select is(count(*), 4::bigint) - from credential_vault_library_ssh_private_key_mapping_override + from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id in ('vl______wvl9', 'vl______wvl10', 'vl______wvl11', 'vl______wvl12'); select is(count(*), 4::bigint) - from credential_vault_library_username_password_mapping_override + from credential_vault_generic_library_username_password_mapping_ovrd where library_id in ('vl______wvl4', 'vl______wvl5', 'vl______wvl6', 'vl______wvl7'); select is(count(*), 8::bigint) - from credential_vault_library_username_password_domain_mapping_ovrd + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id in ('vl______wvl13', 'vl______wvl14', 'vl______wvl15', 'vl______wvl16', 'vl______wvl17', 'vl______wvl18', 'vl______wvl19', 'vl______wvl20'); select is(count(*), 8::bigint) - from credential_vault_library_mapping_override + from credential_vault_generic_library_mapping_override where library_id in ('vl______wvl4', 'vl______wvl5', 'vl______wvl6', 'vl______wvl7', 'vl______wvl9', 'vl______wvl10', 'vl______wvl11', 'vl______wvl12'); -- create test vault tokens diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library_refactor.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library_refactor.sql new file mode 100644 index 0000000000..5720404d96 --- /dev/null +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library_refactor.sql @@ -0,0 +1,599 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: BUSL-1.1 + +-- Tests the refactor around credential_vault_library (and other associated +-- tables/views). It tests that the new structure is setup as expected with all +-- the associated triggers, FKs, constraints, etc. It does not test the refactor +-- where state is present in the database beforehand. For this, see the Go SQL +-- tests in migrations/oss/postgres_99_01_test.go. +-- +-- For extra context, see migration folder 99/README.md. + +begin; + select plan(97); + + -- Redefined credential_vault_library. + select has_table( 'credential_vault_library'); + select has_column( 'credential_vault_library', 'public_id'); + select col_is_pk( 'credential_vault_library', 'public_id'); + select col_not_null('credential_vault_library', 'public_id'); + + select has_column( 'credential_vault_library', 'store_id'); + select col_not_null('credential_vault_library', 'store_id'); + + select has_column( 'credential_vault_library', 'credential_type'); + select col_not_null( 'credential_vault_library', 'credential_type'); + select col_default_is('credential_vault_library', 'credential_type', 'unspecified'); + + select has_column( 'credential_vault_library', 'project_id'); + select col_not_null('credential_vault_library', 'project_id'); + + select has_column( 'credential_vault_library', 'create_time'); + select col_not_null('credential_vault_library', 'create_time'); + + select has_column( 'credential_vault_library', 'update_time'); + select col_not_null('credential_vault_library', 'update_time'); + + select fk_ok('credential_vault_library', ARRAY['public_id', 'store_id', 'credential_type', 'project_id'], 'credential_library', ARRAY['public_id', 'store_id', 'credential_type', 'project_id']); + select fk_ok('credential_vault_library', ARRAY['project_id', 'store_id'], 'credential_vault_store', ARRAY['project_id', 'public_id']); + + select has_trigger('credential_vault_library', 'immutable_columns'); + select has_trigger('credential_vault_library', 'insert_credential_library_subtype'); + select has_trigger('credential_vault_library', 'delete_credential_library_subtype'); + select has_trigger('credential_vault_library', 'update_credential_library_table_update_time'); + + -- Vault generic credential library table. + select has_table('credential_vault_generic_library'); + select has_column( 'credential_vault_generic_library', 'public_id'); + select col_is_pk('credential_vault_generic_library', 'public_id'); + select has_column( 'credential_vault_generic_library', 'store_id'); + select has_column( 'credential_vault_generic_library', 'name'); + select has_column( 'credential_vault_generic_library', 'description'); + select has_column( 'credential_vault_generic_library', 'create_time'); + select has_column( 'credential_vault_generic_library', 'update_time'); + select has_column( 'credential_vault_generic_library', 'version'); + select has_column( 'credential_vault_generic_library', 'vault_path'); + select has_column( 'credential_vault_generic_library', 'http_method'); + select has_column( 'credential_vault_generic_library', 'http_request_body'); + select has_column( 'credential_vault_generic_library', 'credential_type'); + select has_column( 'credential_vault_generic_library', 'project_id'); + + select fk_ok('credential_vault_generic_library', ARRAY['project_id', 'store_id', 'public_id', 'credential_type'], 'credential_vault_library', ARRAY['project_id', 'store_id', 'public_id', 'credential_type']); + + select has_trigger('credential_vault_generic_library', 'immutable_columns'); + select has_trigger('credential_vault_generic_library', 'insert_deleted_id'); + select has_trigger('credential_vault_generic_library', 'insert_credential_vault_library_subtype'); + select has_trigger('credential_vault_generic_library', 'update_credential_vault_library_table_update_time'); + select has_trigger('credential_vault_generic_library', 'delete_credential_vault_library_subtype'); + select has_trigger('credential_vault_generic_library', 'before_insert_credential_vault_library'); + select has_trigger('credential_vault_generic_library', 'hst_on_insert'); + select has_trigger('credential_vault_generic_library', 'hst_on_update'); + select has_trigger('credential_vault_generic_library', 'hst_on_delete'); + + -- Vault generic deleted table. + select hasnt_table('credential_vault_library_deleted'); + select has_table( 'credential_vault_generic_library_deleted'); + + -- Vault generic history table. + select hasnt_table('credential_vault_library_hst'); + select has_table( 'credential_vault_generic_library_hst'); + + -- Mapping overrides: Base table, UP, UPD and SSH PK. + select hasnt_table('credential_vault_library_mapping_override'); + select has_table('credential_vault_generic_library_mapping_override'); + + select hasnt_table('credential_vault_library_username_password_mapping_override'); + select has_table('credential_vault_generic_library_username_password_mapping_ovrd'); + + select hasnt_table('credential_vault_library_username_password_domain_mapping_ovrd'); + select has_table('credential_vault_generic_library_usern_pass_domain_mapping_ovrd'); + + select hasnt_table('credential_vault_library_ssh_private_key_mapping_override'); + select has_table('credential_vault_generic_library_ssh_private_key_mapping_ovrd'); + + -- Views. + select has_view('credential_vault_library_issue_credentials'); + select has_view('whx_credential_dimension_source'); + + select hasnt_view('credential_vault_generic_hst_aggregate'); + select has_view('credential_vault_generic_library_hst_aggregate'); + + select hasnt_view('credential_vault_library_list_lookup'); + select has_view('credential_vault_generic_library_list_lookup'); + + -- Vault dynamic credentials table. + select fk_ok('credential_vault_credential', 'library_id', 'credential_vault_library', 'public_id'); + + -- We can be reasonably sure the structure is as intended. Now we insert data + -- to actually test it. + select lives_ok( + $$ + insert into iam_scope + (parent_id, type, public_id, name) + values + ('global', 'org', 'o_LaIu234Pg6', 'Test Org Scope'); + + insert into iam_scope + (parent_id, type, public_id, name) + values + ('o_LaIu234Pg6', 'project', 'p_31ouN5ldA2', 'Test Project Scope'); + + insert into credential_vault_store + (public_id, project_id, name, vault_address) + values + ('csvlt_5n3A2kJo', 'p_31ouN5ldA2', 'Test Vault Credential Store', 'https://my.vault.instance.local'); + + insert into credential_vault_generic_library + (public_id, store_id, project_id, name, description, vault_path, http_method, http_request_body) + values + ('clvlt_V134iOjA', 'csvlt_5n3A2kJo', 'p_31ouN5ldA2', 'vault_generic1', 'Test vault generic credential library', '/my/vault/path', 'POST', 'my_http_request_body'); + + insert into credential_vault_generic_library + (public_id, store_id, project_id, credential_type, name, description, vault_path, http_method) + values + ('clvlt_j5oK17vG', 'csvlt_5n3A2kJo', 'p_31ouN5ldA2', 'username_password', 'vault_generic2', 'Test vault generic credential library 2', '/my/vault2/path', 'GET'); + + insert into credential_vault_ssh_cert_library + (public_id, store_id, project_id, name, vault_path, username, key_type, key_bits) + values + ('clvsclt_35iWGH12', 'csvlt_5n3A2kJo', 'p_31ouN5ldA2', 'vault_ssh_cert1', '/ssh/issue/mycert', 'myuser', 'ed25519', 0); + + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd + values ('clvlt_V134iOjA', 'custom_username_attr', 'custom_pw_attr', 'custom_domain_attr'); + + insert into credential_vault_generic_library_username_password_mapping_ovrd + values ('clvlt_j5oK17vG', 'custom_username_attr', 'custom_pw_attr'); + $$ + ); + + -- Assert the data was inserted correctly into the subtype tables. + select row_eq( + $$ -- Query: + select public_id, + store_id, + name, + description, + version, + vault_path, + http_method, + http_request_body, + credential_type, + project_id + from credential_vault_generic_library + where public_id = 'clvlt_V134iOjA'; + $$, + row( -- Expect: + 'clvlt_V134iOjA'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'vault_generic1'::wt_name, + 'Test vault generic credential library'::wt_description, + 1::wt_version, + '/my/vault/path'::text, + 'POST'::text, + 'my_http_request_body'::bytea, + 'unspecified'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + + select row_eq( + $$ -- Query: + select public_id, + store_id, + name, + description, + version, + vault_path, + http_method, + http_request_body, + credential_type, + project_id + from credential_vault_generic_library + where public_id = 'clvlt_j5oK17vG'; + $$, + row( -- Expect: + 'clvlt_j5oK17vG'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'vault_generic2'::wt_name, + 'Test vault generic credential library 2'::wt_description, + 1::wt_version, + '/my/vault2/path'::text, + 'GET'::text, + null::bytea, + 'username_password'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + + select row_eq( + $$ -- Query: + select public_id, + store_id, + name, + version, + vault_path, + username, + key_type, + key_bits, + ttl, + key_id, + critical_options, + extensions, + credential_type, + project_id, + additional_valid_principals + from credential_vault_ssh_cert_library + where public_id = 'clvsclt_35iWGH12'; + $$, + row( -- Expect: + 'clvsclt_35iWGH12'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'vault_ssh_cert1'::wt_name, + 1::wt_version, + '/ssh/issue/mycert'::text, + 'myuser'::text, + 'ed25519'::text, + 0::integer, + null::text, + null::text, + null::bytea, + null::bytea, + 'ssh_certificate'::text, + 'p_31ouN5ldA2'::wt_public_id, + null::text + ) + ); + + -- Assert that the data was inserted correctly into the base tables + -- (credential_vault_library and credential_library). + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_vault_library + where public_id = 'clvlt_V134iOjA'; + $$, + row( -- Expect: + 'clvlt_V134iOjA'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'unspecified'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_library + where public_id = 'clvlt_V134iOjA'; + $$, + row( -- Expect: + 'clvlt_V134iOjA'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'unspecified'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_vault_library + where public_id = 'clvlt_j5oK17vG'; + $$, + row( -- Expect: + 'clvlt_j5oK17vG'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'username_password'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_library + where public_id = 'clvlt_j5oK17vG'; + $$, + row( -- Expect: + 'clvlt_j5oK17vG'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'username_password'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_vault_library + where public_id = 'clvsclt_35iWGH12'; + $$, + row( -- Expect: + 'clvsclt_35iWGH12'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'ssh_certificate'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + select row_eq( + $$ -- Query: + select public_id, + store_id, + credential_type, + project_id + from credential_library + where public_id = 'clvsclt_35iWGH12'; + $$, + row( -- Expect: + 'clvsclt_35iWGH12'::wt_public_id, + 'csvlt_5n3A2kJo'::wt_public_id, + 'ssh_certificate'::text, + 'p_31ouN5ldA2'::wt_public_id + ) + ); + + -- Assert that the data was inserted correctly into the history tables. + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_hst + where public_id = 'clvlt_V134iOjA'; + $$, + row(1::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_library_history_base as base + join credential_vault_generic_library_hst as vglh on base.history_id = vglh.history_id + where vglh.public_id = 'clvlt_V134iOjA'; + $$, + row(1::bigint) + ); + + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_hst + where public_id = 'clvlt_j5oK17vG'; + $$, + row(1::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_library_history_base as base + join credential_vault_generic_library_hst as vglh on base.history_id = vglh.history_id + where vglh.public_id = 'clvlt_j5oK17vG'; + $$, + row(1::bigint) + ); + + select row_eq( + $$ + select count(*) + from credential_vault_ssh_cert_library_hst + where public_id = 'clvsclt_35iWGH12'; + $$, + row(1::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_library_history_base as base + join credential_vault_ssh_cert_library_hst as vsclh on base.history_id = vsclh.history_id + where vsclh.public_id = 'clvsclt_35iWGH12'; + $$, + row(1::bigint) + ); + + -- Assert that the data was inserted correctly into the mapping override + -- tables. + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_mapping_override; + $$, + row(2::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd + where library_id = 'clvlt_V134iOjA'; + $$, + row(1::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_username_password_mapping_ovrd + where library_id = 'clvlt_j5oK17vG'; + $$, + row(1::bigint) + ); + + -- Update credential library. Verify that: + -- - The update works. + -- - Version column is incremented. + -- - A new history entry is created both in the base table and subtype table. + select lives_ok( + $$ + update credential_vault_generic_library + set + name = 'vault_generic1_updated', + vault_path = '/my/updated/vault/path' + where public_id = 'clvlt_V134iOjA'; + $$ + ); + + select row_eq( + $$ -- Query: + select public_id, + name, + version, + vault_path + from credential_vault_generic_library + where public_id = 'clvlt_V134iOjA'; + $$, + row( -- Expect: + 'clvlt_V134iOjA'::wt_public_id, + 'vault_generic1_updated'::wt_name, + 2::wt_version, + '/my/updated/vault/path'::text + ) + ); + + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_hst + where public_id = 'clvlt_V134iOjA'; + $$, + row(2::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_library_history_base as base + join credential_vault_generic_library_hst as vglh on base.history_id = vglh.history_id + where vglh.public_id = 'clvlt_V134iOjA'; + $$, + row(2::bigint) + ); + + -- Delete credential library. Verify that: + -- - The delete works. + -- - The deleted credential library id is inserted into the deleted table. + -- - The deleted credential library row is deleted from the base tables. + -- - Mapping overrides that reference this credential library are + -- automatically deleted. + select lives_ok( + $$ + delete from credential_vault_generic_library + where public_id = 'clvlt_j5oK17vG'; + $$ + ); + + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_deleted + where public_id = 'clvlt_j5oK17vG'; + $$, + row(1::bigint) + ); + + select row_eq( + $$ + select count(*) + from credential_vault_library + where public_id = 'clvlt_j5oK17vG'; + $$, + row(0::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_library + where public_id = 'clvlt_j5oK17vG'; + $$, + row(0::bigint) + ); + + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_username_password_mapping_ovrd + where library_id = 'clvlt_j5oK17vG'; + $$, + row(0::bigint) + ); + select row_eq( + $$ + select count(*) + from credential_vault_generic_library_mapping_override + where library_id = 'clvlt_j5oK17vG'; + $$, + row(0::bigint) + ); + + -- Check data in views. + select results_eq( + $$ + select credential_library_id, + credential_library_name + from whx_credential_dimension_source + order by credential_library_name; + $$, + $$ + values + ('cvl_______g1'::wt_public_id, 'green vault library'), + ('cvl__ssh__g1'::wt_public_id, 'green vault ssh library') + $$ + ); + + select results_eq( + $$ + select public_id, + name + from credential_vault_library_issue_credentials + order by name; + $$, + $$ + values + ( 'cvl_______b1'::wt_public_id, 'blue vault library'::wt_name), + ( 'cvl__ssh__b1'::wt_public_id, 'blue vault ssh library'::wt_name), + ( 'cvl_______g1'::wt_public_id, 'green vault library'::wt_name), + ( 'cvl__ssh__g1'::wt_public_id, 'green vault ssh library'::wt_name), + ( 'cvl_______r1'::wt_public_id, 'red vault library'::wt_name), + ( 'cvl__ssh__r1'::wt_public_id, 'red vault ssh library'::wt_name), + ( 'clvlt_V134iOjA'::wt_public_id, 'vault_generic1_updated'::wt_name), + ('clvsclt_35iWGH12'::wt_public_id, 'vault_ssh_cert1'::wt_name) + $$ + ); + + select results_eq( + $$ + select public_id, + name + from credential_vault_generic_library_list_lookup + order by name; + $$, + $$ + values + ( 'cvl_______b1'::wt_public_id, 'blue vault library'::wt_name), + ( 'cvl_______g1'::wt_public_id, 'green vault library'::wt_name), + ( 'cvl_______r1'::wt_public_id, 'red vault library'::wt_name), + ( 'clvlt_V134iOjA'::wt_public_id, 'vault_generic1_updated'::wt_name) + $$ + ); + + select results_eq( + $$ + select public_id, + name + from credential_vault_generic_library_hst_aggregate + order by name; + $$, + $$ + values + ('cvl_______g1'::wt_public_id, 'green vault library'::wt_name) + $$ + ); + + select * from finish(); +rollback; diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library_ssh_private_key_mapping_override.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library_ssh_private_key_mapping_override.sql index 011c7c153f..84b1af3d8d 100644 --- a/internal/db/sqltest/tests/credential/vault/credential_vault_library_ssh_private_key_mapping_override.sql +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library_ssh_private_key_mapping_override.sql @@ -3,10 +3,10 @@ -- credential_vault_library_ssh_private_key_mapping_override tests: -- the following triggers --- insert_credential_vault_library_mapping_override_subtype --- delete_credential_vault_library_mapping_override_subtype +-- insert_credential_vault_generic_library_mapping_override_subtyp +-- delete_credential_vault_generic_library_mapping_override_subtyp -- and the following view --- credential_vault_library_list_lookup +-- credential_vault_generic_library_list_lookup begin; select plan(11); @@ -14,16 +14,16 @@ begin; -- validate the setup data select is(count(*), 4::bigint) - from credential_vault_library_ssh_private_key_mapping_override + from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id in ('vl______wvl9', 'vl______wvl10', 'vl______wvl11', 'vl______wvl12'); select is(count(*), 4::bigint) - from credential_vault_library_mapping_override + from credential_vault_generic_library_mapping_override where library_id in ('vl______wvl9', 'vl______wvl10', 'vl______wvl11', 'vl______wvl12'); prepare select_libraries as select public_id::text, credential_type::text, username_attribute::text, private_key_attribute::text, private_key_passphrase_attribute::text - from credential_vault_library_list_lookup + from credential_vault_generic_library_list_lookup where public_id in ('vl______wvl2', 'vl______wvl8', 'vl______wvl9', 'vl______wvl10', 'vl______wvl11', 'vl______wvl12') order by public_id; @@ -39,28 +39,28 @@ begin; ); -- validate the insert triggers - select is(count(*), 0::bigint) from credential_vault_library_ssh_private_key_mapping_override where library_id = 'vl______wvl8'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl8'; + select is(count(*), 0::bigint) from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id = 'vl______wvl8'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl8'; prepare insert_cvl_ssh_private_key_mapping_override as - insert into credential_vault_library_ssh_private_key_mapping_override + insert into credential_vault_generic_library_ssh_private_key_mapping_ovrd (library_id, username_attribute, private_key_attribute) values ('vl______wvl8', 'my_username', 'my_private_key'); select lives_ok('insert_cvl_ssh_private_key_mapping_override'); - select is(count(*), 1::bigint) from credential_vault_library_ssh_private_key_mapping_override where library_id = 'vl______wvl8'; - select is(count(*), 1::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl8'; + select is(count(*), 1::bigint) from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id = 'vl______wvl8'; + select is(count(*), 1::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl8'; -- validate the delete triggers prepare delete_cvl_ssh_private_key_mapping_override as delete - from credential_vault_library_ssh_private_key_mapping_override + from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id = 'vl______wvl8'; select lives_ok('delete_cvl_ssh_private_key_mapping_override'); - select is(count(*), 0::bigint) from credential_vault_library_ssh_private_key_mapping_override where library_id = 'vl______wvl8'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl8'; + select is(count(*), 0::bigint) from credential_vault_generic_library_ssh_private_key_mapping_ovrd where library_id = 'vl______wvl8'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl8'; select * from finish(); rollback; diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_domain_mapping_ovrd.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_domain_mapping_ovrd.sql index 343adf0bca..d2e08c8998 100644 --- a/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_domain_mapping_ovrd.sql +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_domain_mapping_ovrd.sql @@ -3,10 +3,10 @@ -- credential_vault_library_username_password_domain_mapping_ovrd tests: -- the following triggers --- insert_credential_vault_library_mapping_override_subtype --- delete_credential_vault_library_mapping_override_subtype +-- insert_credential_vault_generic_library_mapping_override_subtyp +-- delete_credential_vault_generic_library_mapping_override_subtyp -- and the following view --- credential_vault_library_list_lookup +-- credential_vault_generic_library_list_lookup begin; @@ -15,16 +15,16 @@ begin; select is(count(*), 8::bigint) - from credential_vault_library_username_password_domain_mapping_ovrd + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id in ('vl______wvl13', 'vl______wvl14', 'vl______wvl15', 'vl______wvl16', 'vl______wvl17', 'vl______wvl18', 'vl______wvl19', 'vl______wvl20'); select is(count(*), 8::bigint) - from credential_vault_library_mapping_override + from credential_vault_generic_library_mapping_override where library_id in ('vl______wvl13', 'vl______wvl14', 'vl______wvl15', 'vl______wvl16', 'vl______wvl17', 'vl______wvl18', 'vl______wvl19', 'vl______wvl20'); prepare select_libraries as select public_id::text, credential_type::text, username_attribute::text, password_attribute::text, domain_attribute::text - from credential_vault_library_list_lookup + from credential_vault_generic_library_list_lookup where public_id in ('vl______wvl2', 'vl______wvl21', 'vl______wvl13', 'vl______wvl14', 'vl______wvl15', 'vl______wvl16', 'vl______wvl17', 'vl______wvl18', 'vl______wvl19', 'vl______wvl20') order by public_id; @@ -45,30 +45,30 @@ begin; -- validate insert triggers - select is(count(*), 0::bigint) from credential_vault_library_username_password_domain_mapping_ovrd where library_id = 'vl______wvl21'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl21'; + select is(count(*), 0::bigint) from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id = 'vl______wvl21'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl21'; prepare insert_cvl_username_password_mapping_override as - insert into credential_vault_library_username_password_domain_mapping_ovrd + insert into credential_vault_generic_library_usern_pass_domain_mapping_ovrd (library_id,username_attribute, password_attribute, domain_attribute) values ('vl______wvl21', 'my_username', 'my_password', 'my_domain'); select lives_ok('insert_cvl_username_password_mapping_override'); - select is(count(*), 1::bigint) from credential_vault_library_username_password_domain_mapping_ovrd where library_id = 'vl______wvl21'; - select is(count(*), 1::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl21'; + select is(count(*), 1::bigint) from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id = 'vl______wvl21'; + select is(count(*), 1::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl21'; -- validate delete triggers prepare delete_cvl_username_password_domain_mapping_ovrd as delete - from credential_vault_library_username_password_domain_mapping_ovrd + from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id = 'vl______wvl21'; select lives_ok('delete_cvl_username_password_domain_mapping_ovrd'); - select is(count(*), 0::bigint) from credential_vault_library_username_password_domain_mapping_ovrd where library_id = 'vl______wvl21'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl21'; + select is(count(*), 0::bigint) from credential_vault_generic_library_usern_pass_domain_mapping_ovrd where library_id = 'vl______wvl21'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl21'; select * from finish(); diff --git a/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_mapping_override.sql b/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_mapping_override.sql index 92ccd468c4..6fb3bef8b2 100644 --- a/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_mapping_override.sql +++ b/internal/db/sqltest/tests/credential/vault/credential_vault_library_username_password_mapping_override.sql @@ -3,10 +3,10 @@ -- credential_vault_library_username_password_mapping_override tests: -- the following triggers --- insert_credential_vault_library_mapping_override_subtype --- delete_credential_vault_library_mapping_override_subtype +-- insert_credential_vault_generic_library_mapping_override_subtyp +-- delete_credential_vault_generic_library_mapping_override_subtyp -- and the following view --- credential_vault_library_list_lookup +-- credential_vault_generic_library_list_lookup begin; select plan(11); @@ -14,16 +14,16 @@ begin; -- validate the setup data select is(count(*), 4::bigint) - from credential_vault_library_username_password_mapping_override + from credential_vault_generic_library_username_password_mapping_ovrd where library_id in ('vl______wvl4', 'vl______wvl5', 'vl______wvl6', 'vl______wvl7'); select is(count(*), 4::bigint) - from credential_vault_library_mapping_override + from credential_vault_generic_library_mapping_override where library_id in ('vl______wvl4', 'vl______wvl5', 'vl______wvl6', 'vl______wvl7'); prepare select_libraries as select public_id::text, credential_type::text, username_attribute::text, password_attribute::text - from credential_vault_library_list_lookup + from credential_vault_generic_library_list_lookup where public_id in ('vl______wvl2', 'vl______wvl3', 'vl______wvl4', 'vl______wvl5', 'vl______wvl6', 'vl______wvl7') order by public_id; @@ -39,28 +39,28 @@ begin; ); -- validate the insert triggers - select is(count(*), 0::bigint) from credential_vault_library_username_password_mapping_override where library_id = 'vl______wvl3'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl3'; + select is(count(*), 0::bigint) from credential_vault_generic_library_username_password_mapping_ovrd where library_id = 'vl______wvl3'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl3'; prepare insert_cvl_username_password_mapping_override as - insert into credential_vault_library_username_password_mapping_override + insert into credential_vault_generic_library_username_password_mapping_ovrd (library_id, username_attribute, password_attribute) values ('vl______wvl3', 'my_username', 'my_password'); select lives_ok('insert_cvl_username_password_mapping_override'); - select is(count(*), 1::bigint) from credential_vault_library_username_password_mapping_override where library_id = 'vl______wvl3'; - select is(count(*), 1::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl3'; + select is(count(*), 1::bigint) from credential_vault_generic_library_username_password_mapping_ovrd where library_id = 'vl______wvl3'; + select is(count(*), 1::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl3'; -- validate the delete triggers prepare delete_cvl_username_password_mapping_override as delete - from credential_vault_library_username_password_mapping_override + from credential_vault_generic_library_username_password_mapping_ovrd where library_id = 'vl______wvl3'; select lives_ok('delete_cvl_username_password_mapping_override'); - select is(count(*), 0::bigint) from credential_vault_library_username_password_mapping_override where library_id = 'vl______wvl3'; - select is(count(*), 0::bigint) from credential_vault_library_mapping_override where library_id = 'vl______wvl3'; + select is(count(*), 0::bigint) from credential_vault_generic_library_username_password_mapping_ovrd where library_id = 'vl______wvl3'; + select is(count(*), 0::bigint) from credential_vault_generic_library_mapping_override where library_id = 'vl______wvl3'; select * from finish(); rollback; diff --git a/internal/db/sqltest/tests/history/dynamic_credentials.sql b/internal/db/sqltest/tests/history/dynamic_credentials.sql index 4705ddbf24..168fb3f3c4 100644 --- a/internal/db/sqltest/tests/history/dynamic_credentials.sql +++ b/internal/db/sqltest/tests/history/dynamic_credentials.sql @@ -13,9 +13,9 @@ begin; select volatility_is('delete_credential_library_history_subtype', 'volatile'); select isnt_strict('delete_credential_library_history_subtype'); - select has_trigger('credential_vault_library_hst', 'insert_credential_library_history_subtype'); - select has_trigger('credential_vault_library_hst', 'delete_credential_library_history_subtype'); - select fk_ok('credential_vault_library_hst', 'history_id', 'credential_library_history_base' , 'history_id'); + select has_trigger('credential_vault_generic_library_hst', 'insert_credential_library_history_subtype'); + select has_trigger('credential_vault_generic_library_hst', 'delete_credential_library_history_subtype'); + select fk_ok('credential_vault_generic_library_hst', 'history_id', 'credential_library_history_base' , 'history_id'); select has_trigger('credential_vault_ssh_cert_library_hst', 'insert_credential_library_history_subtype'); select has_trigger('credential_vault_ssh_cert_library_hst', 'delete_credential_library_history_subtype'); @@ -23,7 +23,7 @@ begin; select results_eq( 'select ' - '(select count(*) from credential_vault_library_hst) + ' + '(select count(*) from credential_vault_generic_library_hst) + ' '(select count(*) from credential_vault_ssh_cert_library_hst)', 'select count(*) from credential_library_history_base' ); diff --git a/internal/db/sqltest/tests/pagination/credential_library.sql b/internal/db/sqltest/tests/pagination/credential_library.sql index 8d1f4a2770..99e662d023 100644 --- a/internal/db/sqltest/tests/pagination/credential_library.sql +++ b/internal/db/sqltest/tests/pagination/credential_library.sql @@ -2,14 +2,18 @@ -- SPDX-License-Identifier: BUSL-1.1 begin; - select plan(9); + select plan(12); -- Verify the trigger functions exist and are declared properly select has_function('update_credential_library_table_update_time'); select volatility_is('update_credential_library_table_update_time', 'volatile'); select isnt_strict('update_credential_library_table_update_time'); - select has_trigger('credential_vault_library', 'update_credential_library_table_update_time'); - select has_trigger('credential_vault_ssh_cert_library', 'update_credential_library_table_update_time'); + + select has_function('update_credential_vault_library_table_update_time'); + select volatility_is('update_credential_vault_library_table_update_time', 'volatile'); + select isnt_strict('update_credential_vault_library_table_update_time'); + select has_trigger('credential_vault_generic_library', 'update_credential_vault_library_table_update_time'); + select has_trigger('credential_vault_ssh_cert_library', 'update_credential_vault_library_table_update_time'); select has_index('credential_library', 'credential_library_create_time_public_id_idx', array['create_time', 'public_id']); select has_index('credential_library', 'credential_library_update_time_public_id_idx', array['update_time', 'public_id']); @@ -17,14 +21,14 @@ begin; -- when an insert into a subtype table happens works, we check that the -- create time of the entries in both tables match prepare credential_library_create_time as select create_time from credential_library where public_id='cvl_______b1'; - prepare credential_vault_library_create_time as select create_time from credential_vault_library where public_id='cvl_______b1'; + prepare credential_vault_library_create_time as select create_time from credential_vault_generic_library where public_id='cvl_______b1'; select results_eq('credential_library_create_time','credential_vault_library_create_time'); -- To test the trigger that updates the update_time of the base table, -- we update one of the existing creds and check that the base table -- entry has the same update_time as the subtype one. - update credential_vault_library set name='blue black vault library' where public_id='cvl_______b1'; + update credential_vault_generic_library set name='blue black vault library' where public_id='cvl_______b1'; prepare credential_library_update_time as select update_time from credential_library where public_id='cvl_______b1'; - prepare credential_vault_library_update_time as select update_time from credential_vault_library where public_id='cvl_______b1'; + prepare credential_vault_library_update_time as select update_time from credential_vault_generic_library where public_id='cvl_______b1'; select results_eq('credential_library_update_time','credential_vault_library_update_time'); select * from finish(); diff --git a/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql b/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql index dbe090e8d0..286040df51 100644 --- a/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql +++ b/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql @@ -5,7 +5,7 @@ begin; select plan(31); select has_table('recording_dynamic_credential'); - select has_view('credential_vault_library_hst_aggregate', 'view for aggregate vault library history info does not exist'); + select has_view('credential_vault_generic_library_hst_aggregate', 'view for aggregate vault generic library history info does not exist'); select has_view('credential_vault_ssh_cert_library_hst_aggregate', 'view for aggregate vault ssh cert library history info does not exist'); -- tests a fk column referencing a history table @@ -55,7 +55,7 @@ begin; prepare select_recording_vault_libraries as select recording_id::text, public_id::text, store_public_id::text, purposes::text - from credential_vault_library_hst_aggregate + from credential_vault_generic_library_hst_aggregate where recording_id = 'sr1_____cora' order by public_id; diff --git a/internal/db/sqltest/tests/wh/credential_dimension/session_multiple_sessions.sql b/internal/db/sqltest/tests/wh/credential_dimension/session_multiple_sessions.sql index a13d3d8d6b..71057a0efd 100644 --- a/internal/db/sqltest/tests/wh/credential_dimension/session_multiple_sessions.sql +++ b/internal/db/sqltest/tests/wh/credential_dimension/session_multiple_sessions.sql @@ -46,7 +46,7 @@ begin; select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget'; -- change the crediential for the target - update credential_vault_library set vault_path = '/secrets/tcp/admin' where public_id = 'vl______wvl1'; + update credential_vault_generic_library set vault_path = '/secrets/tcp/admin' where public_id = 'vl______wvl1'; -- start another session, should result in a new credential dimension insert into session @@ -80,7 +80,7 @@ begin; select is(count(*), 3::bigint) from wh_credential_dimension where organization_id = 'o_____widget'; -- change the crediential again for the target - update credential_vault_library set vault_path = '/secrets/tcp/user' where vault_path = '/secrets/tcp/admin'; + update credential_vault_generic_library set vault_path = '/secrets/tcp/user' where vault_path = '/secrets/tcp/admin'; -- start another session, should result in a one new credential dimensions since one changed insert into session @@ -101,7 +101,7 @@ begin; -- remove all credentials from the target -- then test creating a session - delete from credential_vault_library; + delete from credential_vault_generic_library; insert into session ( project_id, target_id, user_id, auth_token_id, certificate, endpoint, public_id) values diff --git a/internal/db/sqltest/tests/wh/credential_dimension/three_credentials_one_change.sql b/internal/db/sqltest/tests/wh/credential_dimension/three_credentials_one_change.sql index d7d436cdaf..26e912b3c3 100644 --- a/internal/db/sqltest/tests/wh/credential_dimension/three_credentials_one_change.sql +++ b/internal/db/sqltest/tests/wh/credential_dimension/three_credentials_one_change.sql @@ -69,7 +69,7 @@ begin; join wh_session_accumulating_fact on wh_session_accumulating_fact.session_id = wh_session_connection_accumulating_fact.session_id where wh_session_connection_accumulating_fact.session_id = 's1____walter'; - update credential_vault_library set vault_path = '/secrets/tcp/user' where public_id = 'vl______wvl2'; + update credential_vault_generic_library set vault_path = '/secrets/tcp/user' where public_id = 'vl______wvl2'; insert into session ( project_id, target_id, user_id, auth_token_id, certificate, endpoint, public_id)