Console: connection-type-specific fields (remoteCatalogName, warehouse) cannot be set when creating EXTERNAL catalogs
- Dominant language
- TypeScript
- Stars
- 33
- Forks
- 46
- Avg merge
- 1d 4m
- Merged PRs (30d)
- 2
Description
### Summary
The Create Catalog form supports `EXTERNAL` catalogs and collects the shared connection settings, but none of the connection-type-specific fields. The console's `ConnectionConfigInfo` mirrors only the spec's base schema, so the `connectionType` subtype fields have no representation and are unreachable:
| Connection type | Missing field | Spec |
|---|---|---|
| `ICEBERG_REST` | `remoteCatalogName` | `IcebergRestConnectionConfigInfo` |
| `HADOOP` | `warehouse` | `HadoopConnectionConfigInfo` |
| `HIVE` | `warehouse` | `HiveConnectionConfigInfo` |
All three are offered in the form (`CreateCatalogModal.tsx:451-453`). The server accepts the resulting catalog (`201`), but it cannot resolve against a remote that needs the field.
### Details
`ConnectionConfigInfo` in `console/src/types/api.ts:43-48` carries only the base fields:
```ts
export interface ConnectionConfigInfo {
connectionType: "ICEBERG_REST" | "HADOOP" | "HIVE"
uri?: string
authenticationParameters?: unknown
serviceIdentity?: unknown
}
```
and `CreateCatalogModal.tsx:232-239` builds the payload from exactly those:
```ts
const connectionConfigInfo: ConnectionConfigInfo = {
connectionType: values.connectionType!,
}
if (values.conn_uri) connectionConfigInfo.uri = values.conn_uri
if (authenticationParameters)
connectionConfigInfo.authenticationParameters = authenticationParameters
```
In the spec checked in at `console/spec/polaris-management-service.yml:909-947`, `ConnectionConfigInfo` is a discriminated base (`discriminator: propertyName: connectionType`) and `remoteCatalogName` is declared on the `ICEBERG_REST` subtype:
> The name of a remote catalog instance within the remote catalog service; in some older systems this is specified as the 'warehouse' when multiple logical catalogs are served under the same base uri, and often translates into a 'prefix' added to all REST resource paths
Against a prefix-scoped remote, omitting it leaves the proxied request with no prefix and the remote rejects it.
There are vestiges suggesting this was once intended: `CreateCatalogRequest` declares both `icebergRemoteCatalogName?: string` and `hadoopWarehouse?: string` (`console/src/types/api.ts:79-80`), covering two of the three cases, and nothing ever assigns either. The root cause looks like drift between the hand-maintained `console/src/types/api.ts` and the spec sitting one directory over. Related to #103, which tracks the vendored spec drifting from upstream, though this is the inverse direction: hand-written types drifting from the vendored spec.
### Steps to reproduce
1. Run a second Polaris instance as the federation target, with an internal catalog on it. Any prefix-scoped Iceberg REST remote reproduces this; a second Polaris is the easiest.
2. In the console, create a catalog with Type `EXTERNAL`, connection type `ICEBERG_REST`, the remote's `/api/catalog` URI, and OAuth credentials.
3. The catalog is created successfully.
4. `GET /api/catalog/v1//namespaces` returns `400`, with the remote complaining that no warehouse was specified.
`GET /api/management/v1/catalogs/` confirms the cause; no `remoteCatalogName` key is present:
```json
"connectionConfigInfo": {
"connectionType": "ICEBERG_REST",
"uri": "https:///api/catalog",
"authenticationParameters": { ... }
}
```
### Workaround
Create the catalog through the management API instead, adding `"remoteCatalogName": ""` to `connectionConfigInfo`. Namespace and table listing then return `200`.
Note this cannot be fixed after the fact from the UI: `UpdateCatalogRequest` omits `connectionConfigInfo` in both the console's types (`src/types/api.ts:98-102`) and the spec, so a catalog created this way has to be deleted and recreated.
### Impact
The failure is easy to misread. A `400` reads as a malformed request or a permissions problem, when the credentials and connection settings entered in the form are all correct. The only raw-JSON input in the catalog flow is the Properties box on the edit form, which feeds `properties: Record` and cannot carry a connection field, so there is no escape hatch.
### Suggested fix
The spec models `StorageConfigInfo` as a discriminator too (`spec/polaris-management-service.yml:1080-1086`, mapping S3/AZURE/GCS/FILE to their own subtypes), and the console flattens that one into a single interface with `// S3-specific` / `// Azure-specific` / `// GCS-specific` blocks (`console/src/types/api.ts:22-41`), populated conditionally on `storageType` (`CreateCatalogModal.tsx:161-183`). #261 follows that same flattened convention for `kmsUnavailable`.
Following that convention rather than introducing a second style:
- `console/src/types/api.ts:43-48` — add the fields to `ConnectionConfigInfo` under `// ICEBERG_REST-specific` and `// HADOOP/HIVE-specific` comment blocks, mirroring how `StorageConfigInfo` is organised
- `console/src/components/forms/CreateCatalogModal.tsx:53-96` — add them to the zod schema, otherwise they are absent from `FormValues` and `register()` will not typecheck
- `CreateCatalogModal.tsx:232-239` and the `catalogType === "EXTERNAL"` block at `:438` — render conditionally on the selected `connectionType`, and include in the payload when set
- `console/src/pages/CatalogDetails.tsx:274-292` — display alongside `connectionType` and `uri`
Modelling the subtypes properly instead would be more faithful to the spec, but it would diverge from how `StorageConfigInfo` is handled today and is a larger change. Happy either way; I have written it the consistent way above.
I will open a PR along these lines shortly.
### Environment
- `apache/polaris-tools` console at `main` (`e5fea020a`)
- Apache Polaris server 1.5.0
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the ConnectionConfigInfo and CreateCatalogModal.tsx locations named in the issue, then compare them with the ConnectionConfigInfo subtypes in console/spec/polaris-management-service.yml. Check CatalogDetails.tsx for the display path and reproduce the ICEBERG_REST case against a prefix-scoped remote; done means the three subtype fields can be entered, sent, displayed, and the resulting remote namespace request succeeds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100