diff --git a/.sqlx/query-c53448e2f383127421fd3f060629fb2dd02304ce4b51045d729b390497137d75.json b/.sqlx/query-a52cf45e935f28427ba48d2f181134a3bb943053fa46f58c0f1bba820a11fc5a.json similarity index 72% rename from .sqlx/query-c53448e2f383127421fd3f060629fb2dd02304ce4b51045d729b390497137d75.json rename to .sqlx/query-a52cf45e935f28427ba48d2f181134a3bb943053fa46f58c0f1bba820a11fc5a.json index 5724f4c8a74..f7b2dfa9401 100644 --- a/.sqlx/query-c53448e2f383127421fd3f060629fb2dd02304ce4b51045d729b390497137d75.json +++ b/.sqlx/query-a52cf45e935f28427ba48d2f181134a3bb943053fa46f58c0f1bba820a11fc5a.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n id as \"data_plane_id: models::Id\",\n config AS \"config: sqlx::types::Json\",\n deploy_branch AS \"deploy_branch!\",\n logs_token,\n data_plane_name,\n data_plane_fqdn,\n private_links AS \"private_links: Vec>\",\n pulumi_key AS \"pulumi_key\",\n pulumi_stack AS \"pulumi_stack!\"\n FROM data_planes\n WHERE controller_task_id = $1\n ", + "query": "\n SELECT\n id as \"data_plane_id: models::Id\",\n config AS \"config: sqlx::types::Json\",\n deploy_branch AS \"deploy_branch!\",\n logs_token,\n data_plane_name,\n data_plane_fqdn,\n pulumi_key AS \"pulumi_key\",\n pulumi_stack AS \"pulumi_stack!\"\n FROM data_planes\n WHERE controller_task_id = $1\n ", "describe": { "columns": [ { @@ -35,16 +35,11 @@ }, { "ordinal": 6, - "name": "private_links: Vec>", - "type_info": "JsonArray" - }, - { - "ordinal": 7, "name": "pulumi_key", "type_info": "Text" }, { - "ordinal": 8, + "ordinal": 7, "name": "pulumi_stack!", "type_info": "Text" } @@ -61,10 +56,9 @@ false, false, false, - false, true, true ] }, - "hash": "c53448e2f383127421fd3f060629fb2dd02304ce4b51045d729b390497137d75" + "hash": "a52cf45e935f28427ba48d2f181134a3bb943053fa46f58c0f1bba820a11fc5a" } diff --git a/.sqlx/query-cbcdae1de558aa596dedf2cf7500f848bb55b57c1aeb87c2cdba8fb1e85efcac.json b/.sqlx/query-cbcdae1de558aa596dedf2cf7500f848bb55b57c1aeb87c2cdba8fb1e85efcac.json new file mode 100644 index 00000000000..b69562a0d93 --- /dev/null +++ b/.sqlx/query-cbcdae1de558aa596dedf2cf7500f848bb55b57c1aeb87c2cdba8fb1e85efcac.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT config AS \"config!: sqlx::types::Json\"\n FROM data_plane_private_links\n WHERE data_plane_id = $1\n ORDER BY created_at, id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "config!: sqlx::types::Json", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Macaddr8" + ] + }, + "nullable": [ + false + ] + }, + "hash": "cbcdae1de558aa596dedf2cf7500f848bb55b57c1aeb87c2cdba8fb1e85efcac" +} diff --git a/crates/data-plane-controller/src/job/executor.rs b/crates/data-plane-controller/src/job/executor.rs index ee37328e2fe..4fd1c5a8c7a 100644 --- a/crates/data-plane-controller/src/job/executor.rs +++ b/crates/data-plane-controller/src/job/executor.rs @@ -393,7 +393,6 @@ async fn fetch_row_state( logs_token, data_plane_name, data_plane_fqdn, - private_links AS "private_links: Vec>", pulumi_key AS "pulumi_key", pulumi_stack AS "pulumi_stack!" FROM data_planes @@ -411,12 +410,23 @@ async fn fetch_row_state( config.model.name = Some(row.data_plane_name); config.model.fqdn = Some(row.data_plane_fqdn); - // The controller reads desired links from the `private_links` column, which - // the `data_plane_private_links` trigger keeps projected from the per-link - // rows. Reading the table directly is deferred to the contract change that - // drops this column, so the controller has no deploy-ordering dependency on - // the agent-api cutover. - config.model.private_links = row.private_links.into_iter().map(|link| link.0).collect(); + // Desired links are read directly from `data_plane_private_links`, ordered + // deterministically. The id is intentionally not handed to est-dry-dock; + // only the link `config` is, preserving the prior wire shape. + let link_rows = sqlx::query!( + r#" + SELECT config AS "config!: sqlx::types::Json" + FROM data_plane_private_links + WHERE data_plane_id = $1 + ORDER BY created_at, id + "#, + row.data_plane_id as models::Id, + ) + .fetch_all(pool) + .await + .context("failed to fetch data-plane private links")?; + + config.model.private_links = link_rows.into_iter().map(|r| r.config.0).collect(); let stack = if let Some(key) = row.pulumi_key { stack::PulumiStack { diff --git a/supabase/migrations/20260618130000_data_plane_private_links_cutover.sql b/supabase/migrations/20260618130000_data_plane_private_links_cutover.sql new file mode 100644 index 00000000000..b6ef134e55c --- /dev/null +++ b/supabase/migrations/20260618130000_data_plane_private_links_cutover.sql @@ -0,0 +1,42 @@ +-- Cutover step for `data_plane_private_links`: the data-plane controller now +-- reads desired links from the table directly, so the transition projection +-- into the `data_planes.private_links` column is no longer needed. Replace the +-- trigger function with a wake-only version that still sends the controller a +-- converge promptly on any link change. +-- +-- The now-unused `private_links` column is intentionally left in place. Dropping +-- it together with the legacy `*_link_endpoints` columns (all four are projected +-- by the `data_planes_overview` view and the agent-api endpoint resolvers) is a +-- single follow-up cleanup, so the reporting view is recreated once rather than +-- per column. +-- +-- Deploy ordering: roll out the controller binary that reads links from the +-- table before applying this migration, so a controller still reading the +-- column keeps seeing projected updates until it is replaced. + +begin; + +create or replace function internal.on_data_plane_private_links_change() returns trigger + language plpgsql security definer + set search_path to '' + as $$ +declare + v_controller_task_id public.flowid; +begin + select dp.controller_task_id into v_controller_task_id + from public.data_planes dp + where dp.id = coalesce(new.data_plane_id, old.data_plane_id); + + if v_controller_task_id is not null then + perform internal.send_to_task( + v_controller_task_id, + '00:00:00:00:00:00:00:00'::public.flowid, + '"converge"'::json + ); + end if; + + return null; +end; +$$; + +commit;