Repository navigation
[dashboard] Migrate patches to upstream project - #1569
Conversation
WalkthroughThis PR updates dashboard container images with new source commits, refactors API resource fetching from builtin to API-based resources, introduces namespace configuration environment variables, renames branding config keys with CUSTOM_ prefixes, and enhances form field handling for OpenAPI additionalProperties processing. Changes
Sequence DiagramsequenceDiagram
participant UI as Dashboard UI
participant Old as Builtin Resources<br/>(Legacy)
participant New as API Resources<br/>(New)
participant API as Kubernetes API
rect rgb(200, 220, 250)
note over UI,API: Old Flow
UI->>Old: useBuiltinResources()
Old->>API: fetch /api/v1/namespaces
API-->>Old: builtin namespaces
Old-->>UI: resource data
end
rect rgb(220, 250, 200)
note over UI,API: New Flow
UI->>New: useApiResources(apiGroup, apiVersion, resource)
New->>API: fetch /apis/core.cozystack.io/v1alpha1/tenantnamespaces
API-->>New: tenant namespaces
New-->>UI: resource data
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring extra attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
[dashboard] Fix nested lists in addtiionalProperties Signed-off-by: Andrei Kvapil <[email protected]>
2c4d136 to
723eefe
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/system/dashboard/images/openapi-ui/openapi-ui/patches/namespaces.diff (1)
77-89: Keep backlink path configurable.We now hard-code
/api-table/core.cozystack.io/v1alpha1/tenantnamespaces. Any cluster that overrides the namespace API group/version/resource via env vars (which this PR explicitly introduces) will land on the wrong route. Please build the path from the same constants/env-backed values used elsewhere (e.g.,BASE_PROJECTS_API_GROUP,BASE_PROJECTS_VERSION,BASE_PROJECTS_RESOURCE_NAME) instead of hard-coding the Cozystack defaults.Apply this diff to compose the backlink dynamically:
@@ -import { getClusterList } from 'store/clusterList/selectors' +import { getClusterList } from 'store/clusterList/selectors' +import { + BASE_PROJECTS_API_GROUP, + BASE_PROJECTS_VERSION, + BASE_PROJECTS_RESOURCE_NAME, +} from 'constants/customizationApiGroupAndVersion' @@ - return `${baseprefix}/${clusterName}/api-table/core.cozystack.io/v1alpha1/tenantnamespaces` + return `${baseprefix}/${clusterName}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_VERSION}/${BASE_PROJECTS_RESOURCE_NAME}` @@ - return `${baseprefix}/${clusterName}/api-table/core.cozystack.io/v1alpha1/tenantnamespaces` + return `${baseprefix}/${clusterName}/api-table/${BASE_PROJECTS_API_GROUP}/${BASE_PROJECTS_VERSION}/${BASE_PROJECTS_RESOURCE_NAME}`
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/system/dashboard/images/openapi-ui-k8s-bff/Dockerfile(1 hunks)packages/system/dashboard/images/openapi-ui-k8s-bff/patches/namespaces.diff(0 hunks)packages/system/dashboard/images/openapi-ui/Dockerfile(2 hunks)packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/additional-properties-types.diff(1 hunks)packages/system/dashboard/images/openapi-ui/openapi-ui/patches/namespaces.diff(3 hunks)packages/system/dashboard/templates/configmap.yaml(2 hunks)packages/system/dashboard/templates/web.yaml(3 hunks)packages/system/dashboard/values.yaml(1 hunks)
💤 Files with no reviewable changes (1)
- packages/system/dashboard/images/openapi-ui-k8s-bff/patches/namespaces.diff
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-05-14T16:58:01.478Z
Learnt from: nbykov0
Repo: cozystack/cozystack PR: 932
File: packages/system/dashboard/images/kubeapps-apis/Dockerfile:15-17
Timestamp: 2025-05-14T16:58:01.478Z
Learning: When working with Dockerfiles for cross-architecture builds in the kubeapps-apis component, the `TARGETOS` and `TARGETARCH` build arguments should be declared without default values so that Docker's buildx system can automatically set these variables based on the specified target platform.
Applied to files:
packages/system/dashboard/images/openapi-ui-k8s-bff/Dockerfilepackages/system/dashboard/images/openapi-ui/Dockerfile
📚 Learning: 2025-05-14T16:54:50.368Z
Learnt from: nbykov0
Repo: cozystack/cozystack PR: 932
File: packages/apps/kubernetes/images/cluster-autoscaler/Dockerfile:3-4
Timestamp: 2025-05-14T16:54:50.368Z
Learning: In Dockerfiles for the cozystack project, ARG ordering where a variable like ${TARGETARCH} is referenced before being declared can still work correctly in practice because Docker's BuildKit may evaluate the variable only when it's actually used in a FROM statement.
Applied to files:
packages/system/dashboard/images/openapi-ui/Dockerfile
🪛 YAMLlint (1.37.1)
packages/system/dashboard/templates/configmap.yaml
[warning] 22-22: too many spaces after colon
(colons)
[warning] 23-23: too many spaces after colon
(colons)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test redis
- GitHub Check: Test kubernetes-previous
| + let fieldItems: { type: string } | undefined = addProps.items | ||
| + let fieldNestedProperties = addProps.properties || {} | ||
| + let fieldRequired: string | undefined = addProps.required | ||
| + | ||
| + if (nestedProp) { | ||
| + // Use the nested property definition if it exists | ||
| + // Handle type - it can be string or string[] in OpenAPI v2 | ||
| + if (nestedProp.type) { | ||
| + if (Array.isArray(nestedProp.type)) { | ||
| + fieldType = nestedProp.type[0] || addProps.type | ||
| + } else if (typeof nestedProp.type === 'string') { | ||
| + fieldType = nestedProp.type | ||
| + } else { | ||
| + fieldType = addProps.type | ||
| + } | ||
| + } else { | ||
| + fieldType = addProps.type | ||
| + } | ||
| + | ||
| + // Handle items - it can be ItemsObject or ReferenceObject | ||
| + if (nestedProp.items) { | ||
| + // Check if it's a valid ItemsObject with type property | ||
| + if ('type' in nestedProp.items && typeof nestedProp.items.type === 'string') { | ||
| + fieldItems = { type: nestedProp.items.type } | ||
| + } else { | ||
| + fieldItems = addProps.items | ||
| + } | ||
| + } else { | ||
| + fieldItems = addProps.items | ||
| + } |
There was a problem hiding this comment.
Don't strip schema metadata from array item definitions.
When we replace fieldItems with { type: nestedProp.items.type }, any richer schema attached to the array items (nested object properties, enums, $ref, etc.) is discarded. The UI then renders those entries as plain primitives, breaking scenarios where additionalProperties wraps arrays of complex types—exactly the workflows this patch set is meant to improve. We should preserve the full item schema (and keep the wider type for fieldItems) instead of collapsing it to a bare { type: string }.
Apply this diff to keep the full schema intact:
- let fieldItems: { type: string } | undefined = addProps.items
+ let fieldItems: OpenAPIV2.SchemaObject['items'] = addProps.items
...
- if (nestedProp.items) {
- // Check if it's a valid ItemsObject with type property
- if ('type' in nestedProp.items && typeof nestedProp.items.type === 'string') {
- fieldItems = { type: nestedProp.items.type }
- } else {
- fieldItems = addProps.items
- }
- } else {
- fieldItems = addProps.items
- }
+ if (nestedProp.items) {
+ fieldItems = nestedProp.items
+ } else {
+ fieldItems = addProps.items
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| + let fieldItems: { type: string } | undefined = addProps.items | |
| + let fieldNestedProperties = addProps.properties || {} | |
| + let fieldRequired: string | undefined = addProps.required | |
| + | |
| + if (nestedProp) { | |
| + // Use the nested property definition if it exists | |
| + // Handle type - it can be string or string[] in OpenAPI v2 | |
| + if (nestedProp.type) { | |
| + if (Array.isArray(nestedProp.type)) { | |
| + fieldType = nestedProp.type[0] || addProps.type | |
| + } else if (typeof nestedProp.type === 'string') { | |
| + fieldType = nestedProp.type | |
| + } else { | |
| + fieldType = addProps.type | |
| + } | |
| + } else { | |
| + fieldType = addProps.type | |
| + } | |
| + | |
| + // Handle items - it can be ItemsObject or ReferenceObject | |
| + if (nestedProp.items) { | |
| + // Check if it's a valid ItemsObject with type property | |
| + if ('type' in nestedProp.items && typeof nestedProp.items.type === 'string') { | |
| + fieldItems = { type: nestedProp.items.type } | |
| + } else { | |
| + fieldItems = addProps.items | |
| + } | |
| + } else { | |
| + fieldItems = addProps.items | |
| + } | |
| let fieldItems: OpenAPIV2.SchemaObject['items'] = addProps.items | |
| let fieldNestedProperties = addProps.properties || {} | |
| let fieldRequired: string | undefined = addProps.required | |
| if (nestedProp) { | |
| // Use the nested property definition if it exists | |
| // Handle type - it can be string or string[] in OpenAPI v2 | |
| if (nestedProp.type) { | |
| if (Array.isArray(nestedProp.type)) { | |
| fieldType = nestedProp.type[0] || addProps.type | |
| } else if (typeof nestedProp.type === 'string') { | |
| fieldType = nestedProp.type | |
| } else { | |
| fieldType = addProps.type | |
| } | |
| } else { | |
| fieldType = addProps.type | |
| } | |
| // Handle items - it can be ItemsObject or ReferenceObject | |
| if (nestedProp.items) { | |
| fieldItems = nestedProp.items | |
| } else { | |
| fieldItems = addProps.items | |
| } |
🤖 Prompt for AI Agents
In
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/additional-properties-types.diff
around lines 14 to 43, the code replaces fieldItems with a minimal { type:
string } when nestedProp.items exists, which strips richer schema metadata
(properties, enums, $ref) for array items; instead preserve the full item schema
by assigning fieldItems = nestedProp.items (and widen the fieldItems type to
accept the full ItemsObject|ReferenceObject|undefined union), only falling back
to addProps.items if nestedProp.items is absent; do not construct a new object
with just type.
|
Backport failed for Please cherry-pick the changes locally and resolve any conflicts. git fetch origin release-0.37
git worktree add -d .worktree/backport-1569-to-release-0.37 origin/release-0.37
cd .worktree/backport-1569-to-release-0.37
git switch --create backport-1569-to-release-0.37
git cherry-pick -x 723eefea66614b6a621413d0d48e3d5238cd53b6 |
…4317) ## What this PR does A single-replica OpenSearch release stops rolling once any index on it asks for a replica. The copy has nowhere to go on one data node, so the cluster stays yellow for good. The operator's restart gate at v2.8.0 opens on green, or on yellow only when `.opensearch-observability` is the yellow index, and at OpenSearch 2.11.1 that index is `auto_expand_replicas: 0-2`, green on one node. So the gate never opens. Every release gets such an index by itself. The operator sets `plugins.security.audit.type: internal_opensearch`, and the first audited event creates a daily `security-auditlog-*` index with one replica. After that nothing that needs a restart is rolled out, a version upgrade or the move of the HTTP listener onto the cert-manager chain included. This is what timed out the `opensearch` e2e suite on some runs. Both failed runs I read show the same thing in the OpenSearch log: the bootstrap node leaves, `Connection reset` on the transport layer, and `[security-auditlog-<date>] creating index ... shards [1]/[1]` within 40 ms. The security plugin audits that exception (`SecuritySSLNettyTransport` hands it to `AuditLogSslExceptionHandler`), so the reset is what creates the index. Then the operator logs `waiting for health to be green` every ten seconds until the assert gives up. Not sure why the green runs had no audit index before the roll, a green run keeps no snapshot. The fix carries opensearch-project/opensearch-k8s-operator#1569 back to v2.8.0 as a second patch on the in-tree operator image, with the upstream tests. The new gate lets a yellow cluster through once allocation is enabled, every data node has joined and no shard is moving, and `PreparePodForDelete` refuses to restart a node that holds the only active copy of a shard meant to have others. A lone data node is exempt. I left out the third commit of that PR (tiered data roles in `HasDataRole`), the chart renders only the `data` role. A bump would not help: the only operator build after v2.8.0 is `3.0.0-alpha` from January, and its gate holds this case the same way. The patch goes away on the first release that includes #1569. The suite now creates an index with an unassignable replica before it moves the listener, so the roll always runs against a yellow cluster. The catch block also reads cluster health and the shard table from the node, because the operator logs that health held a restart back and never what the health was. The image digest in `values.yaml` stays as it is. Closes #4259 ### Screenshots Not a UI change. ### Downstream repositories Walked the trigger map against the diff: an e2e suite, the operator image's Dockerfile header and patch directory, one comment in the operator package's `values.yaml`. No values key, schema, make target or documented workaround changes. - [x] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: - [ ] [cozystack/community](https://github.com/cozystack/community) - follow-up: ### Release note ```release-note fix(opensearch-operator): a single-replica OpenSearch release no longer gets stuck ahead of every rolling restart once an index with a replica, such as the security audit log or any index created with default settings, leaves the cluster permanently yellow ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved rolling restart handling for clusters that remain yellow, allowing restarts to proceed safely once shard activity has settled. - Prevented restart operations from becoming blocked by temporary shard-allocation settings. - Added safeguards to ensure data is not disrupted while replicas are relocating or initializing. - **Diagnostics** - Added automatic cluster health and shard diagnostics when restart-related test operations time out or encounter issues. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Signed-off-by: Andrei Kvapil [email protected]
What this PR does
Release note
Summary by CodeRabbit
New Features
Bug Fixes
Chores