mirror of https://github.com/hashicorp/boundary
commit
21e61d362e
@ -0,0 +1,129 @@
|
||||
begin;
|
||||
-- replaces check from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter domain wh_public_id drop constraint wh_public_id_check;
|
||||
alter domain wh_public_id add constraint wh_public_id_check
|
||||
check(
|
||||
value = 'None'
|
||||
or
|
||||
value = 'Unknown'
|
||||
or
|
||||
length(trim(value)) > 10
|
||||
);
|
||||
|
||||
create table wh_credential_dimension (
|
||||
-- random id generated using encode(digest(gen_random_bytes(16), 'sha256'), 'base64')
|
||||
-- this is done to prevent conflicts with rows in other clusters
|
||||
-- which enables warehouse data from multiple clusters to be loaded into a
|
||||
-- single database instance
|
||||
key wh_dim_key primary key default wh_dim_key(),
|
||||
|
||||
credential_purpose wh_dim_text,
|
||||
credential_library_id wh_public_id not null,
|
||||
credential_library_type wh_dim_text,
|
||||
credential_library_name wh_dim_text,
|
||||
credential_library_description wh_dim_text,
|
||||
credential_library_vault_path wh_dim_text,
|
||||
credential_library_vault_http_method wh_dim_text,
|
||||
credential_library_vault_http_request_body wh_dim_text,
|
||||
|
||||
credential_store_id wh_public_id not null,
|
||||
credential_store_type wh_dim_text,
|
||||
credential_store_name wh_dim_text,
|
||||
credential_store_description wh_dim_text,
|
||||
credential_store_vault_namespace wh_dim_text,
|
||||
credential_store_vault_address wh_dim_text,
|
||||
|
||||
target_id wh_public_id not null,
|
||||
target_type wh_dim_text,
|
||||
target_name wh_dim_text,
|
||||
target_description wh_dim_text,
|
||||
target_default_port_number integer not null,
|
||||
target_session_max_seconds integer not null,
|
||||
target_session_connection_limit integer not null,
|
||||
|
||||
project_id wt_scope_id not null,
|
||||
project_name wh_dim_text,
|
||||
project_description wh_dim_text,
|
||||
|
||||
organization_id wt_scope_id not null,
|
||||
organization_name wh_dim_text,
|
||||
organization_description wh_dim_text,
|
||||
|
||||
current_row_indicator wh_dim_text,
|
||||
row_effective_time wh_timestamp,
|
||||
row_expiration_time wh_timestamp
|
||||
);
|
||||
|
||||
-- https://www.postgresql.org/docs/current/indexes-partial.html
|
||||
create unique index wh_credential_dim_current_constraint
|
||||
on wh_credential_dimension (credential_library_id, credential_store_id, target_id, credential_purpose)
|
||||
where current_row_indicator = 'Current';
|
||||
|
||||
-- One part of a bridge table to associated the set of wh_credential_dimension with a fact table.
|
||||
-- The other part of the bridge is wh_credential_group_membership.
|
||||
create table wh_credential_group (
|
||||
-- random id generated using encode(digest(gen_random_bytes(16), 'sha256'), 'base64')
|
||||
-- this is done to prevent conflicts with rows in other clusters
|
||||
-- which enables warehouse data from multiple clusters to be loaded into a
|
||||
-- single database instance
|
||||
key wh_dim_key primary key default wh_dim_key()
|
||||
);
|
||||
|
||||
-- The second part of the bridge table. The other part is wh_credential_group.
|
||||
create table wh_credential_group_membership (
|
||||
credential_group_key wh_dim_key not null
|
||||
references wh_credential_group (key)
|
||||
on delete restrict
|
||||
on update cascade,
|
||||
credential_key wh_dim_key not null
|
||||
references wh_credential_dimension (key)
|
||||
on delete restrict
|
||||
on update cascade
|
||||
);
|
||||
|
||||
-- Add "no credentials" and "Unknown" group an dimension.
|
||||
-- When a session has no credentials "no credentials" is used as the "None" value.
|
||||
-- "Unknown" is used for existing data prior to the credential_dimension existing.
|
||||
insert into wh_credential_group
|
||||
(key)
|
||||
values
|
||||
('no credentials'),
|
||||
('Unknown');
|
||||
insert into wh_credential_dimension (
|
||||
key,
|
||||
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_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,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
values
|
||||
(
|
||||
'no credential',
|
||||
'None',
|
||||
'None', 'None', 'None', 'None', 'None', 'None', 'None',
|
||||
'None', 'None', 'None', 'None', 'None', 'None',
|
||||
'None', 'None', 'None', 'None', -1, -1, -1,
|
||||
'00000000000', 'None', 'None',
|
||||
'00000000000', 'None', 'None',
|
||||
'Current', now(), 'infinity'::timestamptz
|
||||
),
|
||||
(
|
||||
'Unknown',
|
||||
'Unknown',
|
||||
'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Unknown',
|
||||
'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Unknown',
|
||||
'Unknown', 'Unknown', 'Unknown', 'Unknown', -1, -1, -1,
|
||||
'00000000000', 'Unknown', 'Unknown',
|
||||
'00000000000', 'Unknown', 'Unknown',
|
||||
'Current', now(), 'infinity'::timestamptz
|
||||
);
|
||||
insert into wh_credential_group_membership
|
||||
(credential_group_key, credential_key)
|
||||
values
|
||||
('no credentials', 'no credential'),
|
||||
('Unknown', 'Unknown');
|
||||
|
||||
commit;
|
||||
@ -0,0 +1,100 @@
|
||||
begin;
|
||||
-- The whx_credential_dimension_source and whx_credential_dimension_target views are used
|
||||
-- by an insert trigger to determine if the current row for the dimension has
|
||||
-- changed and a new one needs to be inserted. The first column in the target view
|
||||
-- must be the current warehouse id and all remaining columns must match the columns
|
||||
-- in the source view.
|
||||
|
||||
-- The whx_credential_dimension_source view shows the current values in the
|
||||
-- operational tables of the credential dimension.
|
||||
create view whx_credential_dimension_source as
|
||||
select -- id is the first column in the target view
|
||||
s.public_id as session_id,
|
||||
coalesce(scd.credential_purpose, 'None') as credential_purpose,
|
||||
cl.public_id as credential_library_id,
|
||||
case
|
||||
when vcl is null then 'None'
|
||||
else 'vault credential library'
|
||||
end as credential_library_type,
|
||||
coalesce(vcl.name, 'None') as credential_library_name,
|
||||
coalesce(vcl.description, 'None') as credential_library_description,
|
||||
coalesce(vcl.vault_path, 'None') as credential_library_vault_path,
|
||||
coalesce(vcl.http_method, 'None') as credential_library_vault_http_method,
|
||||
coalesce(vcl.http_request_body, 'None') as credential_library_vault_http_request_body,
|
||||
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,
|
||||
'tcp target' 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,
|
||||
session as s,
|
||||
credential_library as cl,
|
||||
credential_store as cs,
|
||||
credential_vault_library as vcl,
|
||||
credential_vault_store as vcs,
|
||||
target as t,
|
||||
target_tcp as tt,
|
||||
iam_scope as p,
|
||||
iam_scope as o
|
||||
where scd.library_id = cl.public_id
|
||||
and cl.store_id = cs.public_id
|
||||
and vcl.public_id = cl.public_id
|
||||
and vcs.public_id = cs.public_id
|
||||
and s.public_id = scd.session_id
|
||||
and s.target_id = t.public_id
|
||||
and t.public_id = tt.public_id
|
||||
and p.public_id = t.scope_id
|
||||
and p.type = 'project'
|
||||
and o.public_id = p.parent_id
|
||||
and o.type = 'org';
|
||||
|
||||
create view whx_credential_dimension_target as
|
||||
select key,
|
||||
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_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 wh_credential_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
commit;
|
||||
@ -0,0 +1,170 @@
|
||||
begin;
|
||||
-- wh_upsert_credential_dimension compares the current vaules in the wh_credential_dimension
|
||||
-- with the current values in the operational tables for the given parameters. IF the values
|
||||
-- between operational tables and the wh_credential_dimension differ, a new row is inserted in
|
||||
-- the wh_credential_dimension to match the current values in the operational tables.
|
||||
create function wh_upsert_credential_dimension(p_session_id wt_public_id, p_library_id wt_public_id, p_credential_purpose wh_dim_text)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_credential_dimension_target%rowtype;
|
||||
target whx_credential_dimension_target%rowtype;
|
||||
new_row wh_credential_dimension%rowtype;
|
||||
t_id wt_public_id;
|
||||
begin
|
||||
select s.target_id into strict t_id
|
||||
from session as s
|
||||
where s.public_id = p_session_id;
|
||||
|
||||
select * into target
|
||||
from whx_credential_dimension_target as t
|
||||
where t.credential_library_id = p_library_id
|
||||
and t.target_id = t_id
|
||||
and t.credential_purpose = p_credential_purpose;
|
||||
|
||||
select
|
||||
target.key, t.credential_purpose,
|
||||
t.credential_library_id, t.credential_library_type, t.credential_library_name, t.credential_library_description, t.credential_library_vault_path, t.credential_library_vault_http_method, t.credential_library_vault_http_request_body,
|
||||
t.credential_store_id, t.credential_store_type, t.credential_store_name, t.credential_store_description, t.credential_store_vault_namespace, t.credential_store_vault_address,
|
||||
t.target_id, t.target_type, t.target_name, t.target_description, t.target_default_port_number, t.target_session_max_seconds, t.target_session_connection_limit,
|
||||
t.project_id, t.project_name, t.project_description,
|
||||
t.organization_id, t.organization_name, t.organization_description
|
||||
into src
|
||||
from whx_credential_dimension_source as t
|
||||
where t.credential_library_id = p_library_id
|
||||
and t.session_id = p_session_id
|
||||
and t.target_id = t_id
|
||||
and t.credential_purpose = p_credential_purpose;
|
||||
|
||||
if src is distinct from target then
|
||||
update wh_credential_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where credential_library_id = p_library_id
|
||||
and target_id = t_id
|
||||
and credential_purpose = p_credential_purpose
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
insert into wh_credential_dimension (
|
||||
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_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,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select 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_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,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_credential_dimension_source
|
||||
where credential_library_id = p_library_id
|
||||
and session_id = p_session_id
|
||||
and target_id = t_id
|
||||
and credential_purpose = p_credential_purpose
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
|
||||
return target.key;
|
||||
end
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Run wh_upsert_credential_dimension for session_credential_dynamic row that is inserted.
|
||||
create function wh_insert_session_credential_dynamic()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
perform wh_upsert_credential_dimension(new.session_id, new.library_id, new.credential_purpose);
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
create trigger wh_insert_session_credential_dynamic
|
||||
after insert on session_credential_dynamic
|
||||
for each row
|
||||
execute function wh_insert_session_credential_dynamic();
|
||||
|
||||
-- wh_upsert_credentail_group determines if a new wh_credential_group needs to be
|
||||
-- created due to changes to the coresponding wh_credential_dimensions. It then
|
||||
-- updates the wh_session_accumulating_fact to associate it with the correct wh_credential_group.
|
||||
create function wh_upsert_credentail_group()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
cg_key wh_dim_key;
|
||||
t_id wt_public_id;
|
||||
s_id wt_public_id;
|
||||
c_key wh_dim_key;
|
||||
begin
|
||||
select distinct scd.session_id into strict s_id
|
||||
from new_table as scd;
|
||||
|
||||
select distinct s.target_id into strict t_id
|
||||
from new_table as scd
|
||||
left join session as s on s.public_id = scd.session_id;
|
||||
|
||||
-- based on query written by Michele Gaffney
|
||||
with
|
||||
credential_list (key) as (
|
||||
select key
|
||||
from wh_credential_dimension
|
||||
where target_id = t_id
|
||||
and credential_library_id in (select credential_library_id from new_table)
|
||||
)
|
||||
select distinct credential_group_key into cg_key
|
||||
from wh_credential_group_membership a
|
||||
where a.credential_key in (select key from credential_list)
|
||||
and (select count(key) from credential_list) =
|
||||
(
|
||||
select count(b.credential_key)
|
||||
from wh_credential_group_membership b
|
||||
where a.credential_key = b.credential_key
|
||||
and b.credential_key in (select key from credential_list)
|
||||
)
|
||||
and not exists
|
||||
(
|
||||
select 1
|
||||
from wh_credential_group_membership b
|
||||
where a.credential_key = b.credential_key
|
||||
and b.credential_key not in (select key from credential_list)
|
||||
)
|
||||
;
|
||||
if cg_key is null then
|
||||
insert into wh_credential_group default values returning key into cg_key;
|
||||
for c_key in
|
||||
select key
|
||||
from wh_credential_dimension
|
||||
where target_id = t_id
|
||||
and credential_library_id in (select credential_library_id from new_table)
|
||||
loop
|
||||
insert into wh_credential_group_membership
|
||||
(credential_group_key, credential_key)
|
||||
values
|
||||
(cg_key, c_key);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
update wh_session_connection_accumulating_fact
|
||||
set credential_group_key = cg_key
|
||||
where session_id = s_id;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Run wh_upsert_credentail_group on statement. This assumes that all relevant
|
||||
-- session_credential_dynamic rows are inserted as a single statement and that
|
||||
-- the wh_insert_session_credential_dynamic trigger ran for each row and updated
|
||||
-- the wh_credential_dimensions. Then this statement trigger can run to update the
|
||||
-- bridge tables and wh_session_accumulating_fact.
|
||||
create trigger wh_insert_stmt_session_credential_dynamic
|
||||
after insert on session_credential_dynamic
|
||||
referencing new table as new_table
|
||||
for each statement
|
||||
execute function wh_upsert_credentail_group();
|
||||
commit;
|
||||
@ -0,0 +1,54 @@
|
||||
begin;
|
||||
alter table wh_session_accumulating_fact
|
||||
add column credential_group_key wh_dim_key not null
|
||||
default 'Unknown'
|
||||
references wh_credential_group (key)
|
||||
on delete restrict
|
||||
on update cascade;
|
||||
alter table wh_session_accumulating_fact
|
||||
alter column credential_group_key drop default;
|
||||
|
||||
-- replaces function from 15/01_wh_rename_key_columns.up.sql
|
||||
drop trigger wh_insert_session on session;
|
||||
drop function wh_insert_session;
|
||||
create function wh_insert_session()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
pending_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_state
|
||||
where session_id = new.public_id
|
||||
and state = 'pending'
|
||||
)
|
||||
insert into wh_session_accumulating_fact (
|
||||
session_id,
|
||||
auth_token_id,
|
||||
host_key,
|
||||
user_key,
|
||||
credential_group_key,
|
||||
session_pending_date_key,
|
||||
session_pending_time_key,
|
||||
session_pending_time
|
||||
)
|
||||
select new.public_id,
|
||||
new.auth_token_id,
|
||||
wh_upsert_host(new.host_id, new.host_set_id, new.target_id),
|
||||
wh_upsert_user(new.user_id, new.auth_token_id),
|
||||
'no credentials', -- will be updated by wh_upsert_credentail_group
|
||||
pending_timestamp.date_dim_key,
|
||||
pending_timestamp.time_dim_key,
|
||||
pending_timestamp.ts
|
||||
from pending_timestamp
|
||||
returning * into strict new_row;
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
create trigger wh_insert_session
|
||||
after insert on session
|
||||
for each row
|
||||
execute function wh_insert_session();
|
||||
commit;
|
||||
@ -0,0 +1,75 @@
|
||||
begin;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
add column credential_group_key wh_dim_key not null
|
||||
default 'Unknown'
|
||||
references wh_credential_group (key)
|
||||
on delete restrict
|
||||
on update cascade;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
alter column credential_group_key drop default;
|
||||
|
||||
-- replaces function from 15/01_wh_rename_key_columns.up.sql
|
||||
drop trigger wh_insert_session_connection on session_connection;
|
||||
drop function wh_insert_session_connection;
|
||||
create function wh_insert_session_connection()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_connection_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
authorized_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_connection_state
|
||||
where connection_id = new.public_id
|
||||
and state = 'authorized'
|
||||
),
|
||||
session_dimension (host_dim_key, user_dim_key, credential_group_dim_key) as (
|
||||
select host_key, user_key, credential_group_key
|
||||
from wh_session_accumulating_fact
|
||||
where session_id = new.session_id
|
||||
)
|
||||
insert into wh_session_connection_accumulating_fact (
|
||||
connection_id,
|
||||
session_id,
|
||||
host_key,
|
||||
user_key,
|
||||
credential_group_key,
|
||||
connection_authorized_date_key,
|
||||
connection_authorized_time_key,
|
||||
connection_authorized_time,
|
||||
client_tcp_address,
|
||||
client_tcp_port_number,
|
||||
endpoint_tcp_address,
|
||||
endpoint_tcp_port_number,
|
||||
bytes_up,
|
||||
bytes_down
|
||||
)
|
||||
select new.public_id,
|
||||
new.session_id,
|
||||
session_dimension.host_dim_key,
|
||||
session_dimension.user_dim_key,
|
||||
session_dimension.credential_group_dim_key,
|
||||
authorized_timestamp.date_dim_key,
|
||||
authorized_timestamp.time_dim_key,
|
||||
authorized_timestamp.ts,
|
||||
new.client_tcp_address,
|
||||
new.client_tcp_port,
|
||||
new.endpoint_tcp_address,
|
||||
new.endpoint_tcp_port,
|
||||
new.bytes_up,
|
||||
new.bytes_down
|
||||
from authorized_timestamp,
|
||||
session_dimension
|
||||
returning * into strict new_row;
|
||||
perform wh_rollup_connections(new.session_id);
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_connection
|
||||
after insert on session_connection
|
||||
for each row
|
||||
execute function wh_insert_session_connection();
|
||||
commit;
|
||||
|
||||
@ -0,0 +1,189 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/auth/oidc"
|
||||
"github.com/hashicorp/boundary/internal/authtoken"
|
||||
"github.com/hashicorp/boundary/internal/credential"
|
||||
"github.com/hashicorp/boundary/internal/credential/vault"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/session"
|
||||
"github.com/hashicorp/boundary/internal/target"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMigrations_CredentialDimension(t *testing.T) {
|
||||
const (
|
||||
priorMigration = 15002
|
||||
currentMigration = 16005
|
||||
)
|
||||
|
||||
t.Parallel()
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
ctx := context.Background()
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
|
||||
require.NoError(err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(c())
|
||||
})
|
||||
d, err := sql.Open(dialect, u)
|
||||
require.NoError(err)
|
||||
|
||||
// migration to the prior migration (before the one we want to test)
|
||||
oState := schema.TestCloneMigrationStates(t)
|
||||
nState := schema.TestCreatePartialMigrationState(oState["postgres"], priorMigration)
|
||||
oState["postgres"] = nState
|
||||
|
||||
m, err := schema.NewManager(ctx, dialect, d, schema.WithMigrationStates(oState))
|
||||
require.NoError(err)
|
||||
|
||||
assert.NoError(m.RollForward(ctx))
|
||||
state, err := m.CurrentState(ctx)
|
||||
require.NoError(err)
|
||||
assert.Equal(priorMigration, state.DatabaseSchemaVersion)
|
||||
assert.False(state.Dirty)
|
||||
|
||||
// okay, now we can seed the database with test data
|
||||
conn, err := gorm.Open(dialect, u)
|
||||
require.NoError(err)
|
||||
|
||||
rw := db.New(conn)
|
||||
wrapper := db.TestWrapper(t)
|
||||
|
||||
org, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
|
||||
require.NotNil(prj)
|
||||
assert.NotEmpty(prj.GetPublicId())
|
||||
|
||||
hc := static.TestCatalogs(t, conn, prj.GetPublicId(), 1)[0]
|
||||
hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0]
|
||||
h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0]
|
||||
static.TestSetMembers(t, conn, hs.GetPublicId(), []*static.Host{h})
|
||||
|
||||
tar := target.TestTcpTarget(t, conn, prj.GetPublicId(), "test", target.WithHostSources([]string{hs.GetPublicId()}))
|
||||
var sessions []*session.Session
|
||||
|
||||
kmsCache := kms.TestKms(t, conn, wrapper)
|
||||
databaseWrapper, err := kmsCache.GetWrapper(ctx, org.GetPublicId(), kms.KeyPurposeDatabase)
|
||||
require.NoError(err)
|
||||
|
||||
{
|
||||
at := authtoken.TestAuthToken(t, conn, kmsCache, org.GetPublicId())
|
||||
uId := at.GetIamUserId()
|
||||
|
||||
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
|
||||
UserId: uId,
|
||||
HostId: h.GetPublicId(),
|
||||
TargetId: tar.GetPublicId(),
|
||||
HostSetId: hs.GetPublicId(),
|
||||
AuthTokenId: at.GetPublicId(),
|
||||
ScopeId: prj.GetPublicId(),
|
||||
Endpoint: "tcp://127.0.0.1:22",
|
||||
})
|
||||
sessions = append(sessions, sess)
|
||||
}
|
||||
|
||||
{
|
||||
at := testOidcAuthToken(t, conn, kmsCache, databaseWrapper, org.GetPublicId())
|
||||
uId := at.GetIamUserId()
|
||||
creds := testSessionCredentialParams(t, conn, kmsCache, wrapper, tar)
|
||||
|
||||
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
|
||||
UserId: uId,
|
||||
HostId: h.GetPublicId(),
|
||||
TargetId: tar.GetPublicId(),
|
||||
HostSetId: hs.GetPublicId(),
|
||||
AuthTokenId: at.GetPublicId(),
|
||||
ScopeId: prj.GetPublicId(),
|
||||
Endpoint: "tcp://127.0.0.1:22",
|
||||
DynamicCredentials: creds,
|
||||
})
|
||||
sessions = append(sessions, sess)
|
||||
}
|
||||
|
||||
sessionRepo, err := session.NewRepository(rw, rw, kmsCache)
|
||||
require.NoError(err)
|
||||
|
||||
count, err := sessionRepo.TerminateCompletedSessions(ctx)
|
||||
assert.NoError(err)
|
||||
assert.Zero(count)
|
||||
|
||||
for _, sess := range sessions {
|
||||
// call TerminateSession
|
||||
_, err = sessionRepo.TerminateSession(ctx, sess.GetPublicId(), 1, session.ClosedByUser)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
// now we're ready for the migration we want to test.
|
||||
oState = schema.TestCloneMigrationStates(t)
|
||||
nState = schema.TestCreatePartialMigrationState(oState["postgres"], currentMigration)
|
||||
oState["postgres"] = nState
|
||||
|
||||
m, err = schema.NewManager(ctx, dialect, d, schema.WithMigrationStates(oState))
|
||||
require.NoError(err)
|
||||
|
||||
assert.NoError(m.RollForward(ctx))
|
||||
state, err = m.CurrentState(ctx)
|
||||
require.NoError(err)
|
||||
assert.Equal(currentMigration, state.DatabaseSchemaVersion)
|
||||
assert.False(state.Dirty)
|
||||
}
|
||||
|
||||
func testOidcAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper, scopeId string) *authtoken.AuthToken {
|
||||
t.Helper()
|
||||
|
||||
authMethod := oidc.TestAuthMethod(
|
||||
t, conn, wrapper, scopeId, oidc.ActivePrivateState,
|
||||
"alice-rp", "fido",
|
||||
oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://www.alice.com")[0]),
|
||||
oidc.WithSigningAlgs(oidc.RS256),
|
||||
oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://www.alice.com/callback")[0]),
|
||||
)
|
||||
acct := oidc.TestAccount(t, conn, authMethod, "test-subject")
|
||||
|
||||
ctx := context.Background()
|
||||
rw := db.New(conn)
|
||||
iamRepo, err := iam.NewRepository(rw, rw, kms)
|
||||
require.NoError(t, err)
|
||||
|
||||
u := iam.TestUser(t, iamRepo, scopeId, iam.WithAccountIds(acct.PublicId))
|
||||
|
||||
repo, err := authtoken.NewRepository(rw, rw, kms)
|
||||
require.NoError(t, err)
|
||||
|
||||
at, err := repo.CreateAuthToken(ctx, u, acct.GetPublicId())
|
||||
require.NoError(t, err)
|
||||
return at
|
||||
}
|
||||
|
||||
func testSessionCredentialParams(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper, tar *target.TcpTarget) []*session.DynamicCredential {
|
||||
t.Helper()
|
||||
rw := db.New(conn)
|
||||
|
||||
ctx := context.Background()
|
||||
stores := vault.TestCredentialStores(t, conn, wrapper, tar.ScopeId, 1)
|
||||
libs := vault.TestCredentialLibraries(t, conn, wrapper, stores[0].GetPublicId(), 2)
|
||||
|
||||
targetRepo, err := target.NewRepository(rw, rw, kms)
|
||||
require.NoError(t, err)
|
||||
_, _, _, err = targetRepo.AddTargetCredentialSources(ctx, tar.GetPublicId(), tar.GetVersion(), []string{libs[0].PublicId, libs[1].PublicId})
|
||||
require.NoError(t, err)
|
||||
creds := []*session.DynamicCredential{
|
||||
session.NewDynamicCredential(libs[0].GetPublicId(), credential.ApplicationPurpose),
|
||||
session.NewDynamicCredential(libs[0].GetPublicId(), credential.IngressPurpose),
|
||||
session.NewDynamicCredential(libs[1].GetPublicId(), credential.EgressPurpose),
|
||||
}
|
||||
return creds
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
begin;
|
||||
select plan(2);
|
||||
|
||||
insert into wh_credential_dimension (
|
||||
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_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,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
) values (
|
||||
'application',
|
||||
'vl______wvl1', 'vault credential library', 'gidget vault library', 'None', '/secrets', 'GET', '\x4e6f6e65',
|
||||
'vs_______wvs', 'vault credential store', 'widget vault store', 'None', 'default', 'https://vault.widget',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None',
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
);
|
||||
|
||||
update wh_credential_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where credential_library_id = 'vl______wvl1'
|
||||
and credential_store_id = 'vs_______wvs'
|
||||
and target_id = 't_________wb'
|
||||
and credential_purpose = 'application'
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
insert into wh_credential_dimension (
|
||||
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_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,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
) values (
|
||||
'application',
|
||||
'vl______wvl1', 'vault credential library', 'gidget vault library', 'None', '/secrets', 'GET', '\x4e6f6e65',
|
||||
'vs_______wvs', 'vault credential store', 'widget vault store', 'None', 'default', 'https://vault.widget',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None',
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
);
|
||||
|
||||
select is(count(*), 2::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget' and current_row_indicator = 'Current';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@ -0,0 +1,108 @@
|
||||
-- session_multiple_sessions tests the wh_credential_dimension when
|
||||
-- multiple sessions are created using.
|
||||
begin;
|
||||
select plan(13);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new credentials dimension
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application');
|
||||
select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * same user
|
||||
-- * same auth
|
||||
-- * same host
|
||||
-- should not result in a new credential dimension
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's2____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s2____walter', 'vl______wvl1', null, 'application');
|
||||
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';
|
||||
|
||||
-- start another session, should result in a new credential dimension
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's3____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s3____walter', 'vl______wvl1', null, 'application');
|
||||
select is(count(*), 2::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- start another session, should result in a one new credential dimensions
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's4____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s4____walter', 'vl______wvl1', null, 'application'),
|
||||
('s4____walter', 'vl______wvl2', null, 'application');
|
||||
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';
|
||||
|
||||
-- start another session, should result in a one new credential dimensions since one changed
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's5____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s5____walter', 'vl______wvl1', null, 'application'),
|
||||
('s5____walter', 'vl______wvl2', null, 'application');
|
||||
select is(count(*), 4::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 2::bigint) from wh_credential_dimension where organization_id = 'o_____widget' and current_row_indicator = 'Current';
|
||||
|
||||
-- remove all credentials from the target
|
||||
-- then test creating a session
|
||||
delete from credential_vault_library;
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's6____walter');
|
||||
select is(count(*), 4::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(credential_group_key, 'no credentials') from wh_session_accumulating_fact where session_id = 's6____walter';
|
||||
insert into session_connection
|
||||
(session_id, public_id)
|
||||
values
|
||||
('s6____walter', 'sc6____walter');
|
||||
select is(credential_group_key, 'no credentials') from wh_session_connection_accumulating_fact where session_id = 's6____walter';
|
||||
|
||||
-- insert into a session for a target that never had any credentials associated with it.
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________ws', 's___1ws-sths', 'h_____ws__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's7____walter');
|
||||
select is(count(*), 4::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(credential_group_key, 'no credentials') from wh_session_accumulating_fact where session_id = 's7____walter';
|
||||
insert into session_connection
|
||||
(session_id, public_id)
|
||||
values
|
||||
('s7____walter', 'sc7____walter');
|
||||
select is(credential_group_key, 'no credentials') from wh_session_connection_accumulating_fact where session_id = 's7____walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@ -0,0 +1,33 @@
|
||||
-- session_update tests the wh_credential_dimension when
|
||||
-- a session is inserted and then updated.
|
||||
begin;
|
||||
select plan(3);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- update session, should not impact wh_credential_dimension
|
||||
update session set
|
||||
version = 2
|
||||
where
|
||||
public_id = 's1____walter';
|
||||
|
||||
select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
-- three_credentials_one_change tests that:
|
||||
-- when a session with three credentials is created
|
||||
-- three wh_credential_dimensions are created
|
||||
-- then when one of the credential libraries is updated
|
||||
-- and a new session is created
|
||||
-- only one of the wh_credential_dimensions is updated
|
||||
begin;
|
||||
select plan(4);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- insert session and session_credential_dynamic, should result in a three new credential dimensions
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application'),
|
||||
('s1____walter', 'vl______wvl2', null, 'application'),
|
||||
('s1____walter', 'vl______wvl3', null, 'application');
|
||||
|
||||
select is(count(*), 3::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
|
||||
update credential_vault_library set vault_path = '/secrets/tcp/user' where public_id = 'vl______wvl2';
|
||||
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's2____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s2____walter', 'vl______wvl1', null, 'application'),
|
||||
('s2____walter', 'vl______wvl2', null, 'application'),
|
||||
('s2____walter', 'vl______wvl3', null, 'application');
|
||||
|
||||
select is(count(*), 4::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 3::bigint) from wh_credential_dimension where organization_id = 'o_____widget' and current_row_indicator = 'Current';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
-- source tests the whx_credential_dimension_source view.
|
||||
begin;
|
||||
select plan(1);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application');
|
||||
|
||||
select is(s.*, row(
|
||||
's1____walter',
|
||||
'application', -- credential_purpose,
|
||||
'vl______wvl1', -- credential_library_id,
|
||||
'vault credential library', -- credential_library_type,
|
||||
'widget vault library', -- credential_library_name,
|
||||
'None', -- credential_library_description,
|
||||
'/secrets', -- credential_library_vault_path,
|
||||
'GET', -- credential_library_vault_http_method,
|
||||
'None', -- credential_library_vault_http_request_body,
|
||||
|
||||
'vs_______wvs', -- credential_store_id,
|
||||
'vault credential store', -- credential_store_type,
|
||||
'widget vault store', -- credential_store_name,
|
||||
'None', -- credential_store_description,
|
||||
'default', -- credential_store_vault_namespace,
|
||||
'https://vault.widget', -- credential_store_vault_address,
|
||||
|
||||
't_________wb', -- target_id,
|
||||
'tcp target', -- target_type,
|
||||
'Big Widget Target', -- target_name,
|
||||
'None', -- target_description,
|
||||
0, -- target_default_port_number,
|
||||
28800, -- target_session_max_seconds,
|
||||
1, -- target_session_connection_limit,
|
||||
|
||||
'p____bwidget', -- project_id,
|
||||
'Big Widget Factory', -- project_name,
|
||||
'None', -- project_description,
|
||||
'o_____widget', -- organization_id,
|
||||
'Widget Inc', -- organization_name,
|
||||
'None' -- organization_description
|
||||
)::whx_credential_dimension_source)
|
||||
from whx_credential_dimension_source as s
|
||||
where s.target_id = 't_________wb';
|
||||
|
||||
rollback;
|
||||
@ -0,0 +1,44 @@
|
||||
-- target tests teh whx_credential_dimension_target view.
|
||||
begin;
|
||||
select plan(2);
|
||||
|
||||
select is_empty($$select * from whx_credential_dimension_target where target_id = 't_________wb'$$);
|
||||
|
||||
insert into wh_credential_dimension
|
||||
(
|
||||
key,
|
||||
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_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,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
values
|
||||
(
|
||||
'wcd________1',
|
||||
'application',
|
||||
'vl_______wvl', 'vault credential library', 'widget vault library', 'None', '/secrets', 'GET', 'None',
|
||||
'vs_______wvs', 'vault credential store', 'widget vault store', 'None', 'blue', 'https://vault.widget',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None',
|
||||
'Current', '2021-07-21T12:01'::timestamptz, 'infinity'::timestamptz
|
||||
);
|
||||
|
||||
select is(t.*, row(
|
||||
'wcd________1',
|
||||
'application',
|
||||
'vl_______wvl', 'vault credential library', 'widget vault library', 'None', '/secrets', 'GET', 'None',
|
||||
'vs_______wvs', 'vault credential store', 'widget vault store', 'None', 'blue', 'https://vault.widget',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None'
|
||||
)::whx_credential_dimension_target)
|
||||
from whx_credential_dimension_target as t
|
||||
where t.target_id = 't_________wb';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
--- insert tests a simple insert of session_credential_dynamic
|
||||
begin;
|
||||
select plan(6);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
-- ensure no existing dimensions or bridge table rows
|
||||
select is(count(*), 0::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 0::bigint) from wh_credential_group_membership where credential_group_key != 'no credentials' and credential_group_key != 'Unknown';
|
||||
select is(count(*), 0::bigint) from wh_credential_group where key != 'no credentials' and key != 'Unknown';
|
||||
|
||||
--- insert single credential
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 1::bigint) from wh_credential_group_membership where credential_group_key != 'no credentials' and credential_group_key != 'Unknown';
|
||||
select is(count(*), 1::bigint) from wh_credential_group where key != 'no credentials' and key != 'Unknown';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@ -0,0 +1,29 @@
|
||||
--- insert_multiple tests inserting multiple session_credential_dynamic as a single statement
|
||||
begin;
|
||||
select plan(6);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 0::bigint) from wh_credential_group_membership where credential_group_key != 'no credentials' and credential_group_key != 'Unknown';
|
||||
select is(count(*), 0::bigint) from wh_credential_group where key != 'no credentials' and key != 'Unknown';
|
||||
|
||||
--- multiple single credentials
|
||||
insert into session
|
||||
( scope_id, target_id, host_set_id, host_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bwidget', 't_________wb', 's___1wb-sths', 'h_____wb__01', 'u_____walter', 'tok___walter', 'abc'::bytea, 'ep1', 's1____walter');
|
||||
insert into session_credential_dynamic
|
||||
( session_id, library_id, credential_id, credential_purpose)
|
||||
values
|
||||
('s1____walter', 'vl______wvl1', null, 'application'),
|
||||
('s1____walter', 'vl______wvl2', null, 'application'),
|
||||
('s1____walter', 'vl______wvl3', null, 'application'),
|
||||
('s1____walter', 'vl______wvl3', null, 'egress');
|
||||
|
||||
select is(count(*), 4::bigint) from wh_credential_dimension where organization_id = 'o_____widget';
|
||||
select is(count(*), 4::bigint) from wh_credential_group_membership where credential_group_key != 'no credentials' and credential_group_key != 'Unknown';
|
||||
select is(count(*), 1::bigint) from wh_credential_group where key != 'no credentials' and key != 'Unknown';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
Loading…
Reference in new issue