Skip to content

Commit dba3308

Browse files
fuziontechclaude
andauthored
fix(admin): admit iceberg fields in warehouse PUT strict-decode (#557)
PR #554 added the Iceberg fields to ManagedWarehouse (configstore) and to the upsert column allowlist, but missed the strict-decode struct managedWarehouseRequest that gates which top-level keys a PUT body may carry. The doc comment on that struct literally warns: "If you add a field here without a matching tag on ManagedWarehouse, strict decode will accept it and the merge will silently drop it." Without this fix, `PUT /orgs/<id>/warehouse` with `{"iceberg":{...}}` returns 400 "unknown field iceberg" — making it impossible to enable Iceberg via admin API on existing warehouses (the whole reason the drift correction in #555 exists). Adds the matching test mirroring TestPutWarehouseDisablesPgBouncerWhenSetToFalse. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2acc015 commit dba3308

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

controlplane/admin/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ type managedWarehouseRequest struct {
523523
MetadataStore configstore.ManagedWarehouseMetadataStore `json:"metadata_store"`
524524
PgBouncer configstore.ManagedWarehousePgBouncer `json:"pgbouncer"`
525525
S3 configstore.ManagedWarehouseS3 `json:"s3"`
526+
Iceberg configstore.ManagedWarehouseIceberg `json:"iceberg"`
526527
WorkerIdentity configstore.ManagedWarehouseWorkerIdentity `json:"worker_identity"`
527528
WarehouseDatabaseCredentials configstore.SecretRef `json:"warehouse_database_credentials"`
528529
MetadataStoreCredentials configstore.SecretRef `json:"metadata_store_credentials"`
@@ -536,6 +537,8 @@ type managedWarehouseRequest struct {
536537
MetadataStoreStatusMessage string `json:"metadata_store_status_message"`
537538
S3State configstore.ManagedWarehouseProvisioningState `json:"s3_state"`
538539
S3StatusMessage string `json:"s3_status_message"`
540+
IcebergState configstore.ManagedWarehouseProvisioningState `json:"iceberg_state"`
541+
IcebergStatusMessage string `json:"iceberg_status_message"`
539542
IdentityState configstore.ManagedWarehouseProvisioningState `json:"identity_state"`
540543
IdentityStatusMessage string `json:"identity_status_message"`
541544
SecretsState configstore.ManagedWarehouseProvisioningState `json:"secrets_state"`

controlplane/admin/api_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,25 @@ func TestPutWarehouseDisablesPgBouncerWhenSetToFalse(t *testing.T) {
532532
}
533533
}
534534

535+
func TestPutWarehouseEnablesIcebergWhenSetToTrue(t *testing.T) {
536+
store := newFakeAPIStore()
537+
seedOrgWithWarehouse(store, "analytics")
538+
router := newTestAPIRouter(store)
539+
540+
body := []byte(`{"iceberg": {"enabled": true}}`)
541+
req := httptest.NewRequest(http.MethodPut, "/api/v1/orgs/analytics/warehouse", bytes.NewReader(body))
542+
req.Header.Set("Content-Type", "application/json")
543+
rec := httptest.NewRecorder()
544+
router.ServeHTTP(rec, req)
545+
546+
if rec.Code != http.StatusOK {
547+
t.Fatalf("status = %d, want %d: %s", rec.Code, http.StatusOK, rec.Body.String())
548+
}
549+
if !store.warehouses["analytics"].Iceberg.Enabled {
550+
t.Fatal("expected iceberg.enabled=true after PUT")
551+
}
552+
}
553+
535554
func TestPutWarehousePreservesNestedFieldsOnPartialUpdate(t *testing.T) {
536555
store := newFakeAPIStore()
537556
seedOrgWithWarehouse(store, "analytics")

0 commit comments

Comments
 (0)