Skip to content

[dashboard] Migrate patches to upstream project - #1569

Merged
Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
dashboard-patches
Nov 4, 2025
Merged

Andrei Kvapil (kvaps) merged 1 commit into
mainfrom
dashboard-patches

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Nov 1, 2025 •

Copy link
Copy Markdown
Member

Signed-off-by: Andrei Kvapil [email protected]

What this PR does

Release note

[dashboard] Migrate patches to upstream project
[dashboard] Fix nested lists in addtiionalProperties

Summary by CodeRabbit

  • New Features

    • Enhanced form generation with improved type inference and nested property resolution for dynamic form fields.
  • Bug Fixes

    • Fixed stream data handling issues and improved form field value normalization.
    • Better support for array item initialization with sensible defaults based on field types.
  • Chores

    • Updated API endpoints for namespace resource management.
    • Updated container images and configurations.
    • Improved tenant branding configuration structure.

@coderabbitai

coderabbitai Bot commented Nov 1, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

This 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

Cohort / File(s) Summary
openapi-ui-k8s-bff Image Build
packages/system/dashboard/images/openapi-ui-k8s-bff/Dockerfile
Removed git installation in builder stage; updated COMMIT_REF for source tarball; removed local patches directory and git apply steps for patch application.
openapi-ui-k8s-bff Namespaces Patch
packages/system/dashboard/images/openapi-ui-k8s-bff/patches/namespaces.diff
Modified prepareFormProps.ts to remove content-length header and changed API endpoint from /api/v1/namespaces to /apis/core.cozystack.io/v1alpha1/tenantnamespaces.
openapi-ui Image Build
packages/system/dashboard/images/openapi-ui/Dockerfile
Updated COMMIT references for openapi-k8s-toolkit and openapi-ui source tarballs.
openapi-ui Form Handling Patches
packages/system/dashboard/images/openapi-ui/openapi-k8s-toolkit/patches/additional-properties-types.diff
Enhanced OpenAPI v2 handling in FormObjectFromSwagger, FormStringInput, casts, and utils components: improved additionalProperties field metadata resolution, value normalization for multiline detection, type inference from values, and default value initialization for array items.
openapi-ui Namespaces Patch
packages/system/dashboard/images/openapi-ui/openapi-ui/patches/namespaces.diff
Replaced useBuiltinResources with useApiResources; updated imports and API configuration constants; changed resource fetch calls to use API-based endpoints with apiGroup/apiVersion; updated backlink logic to use tenantnamespaces API paths.
Dashboard ConfigMap Template
packages/system/dashboard/templates/configmap.yaml
Renamed tenant/logo config keys from TENANT_TEXT/LOGO_SVG to CUSTOM_TENANT_TEXT/CUSTOM_LOGO_SVG; updated tenant version reference from v0.37.0 to latest; changed logo flag from "false" to empty string.
Dashboard Web Deployment Template
packages/system/dashboard/templates/web.yaml
Added BASE_NAMESPACE_FULL_PATH environment variable in first container; added CUSTOM_NAMESPACE_API_RESOURCE_* variables in second container; renamed config map references to CUSTOM_TENANT_TEXT and CUSTOM_LOGO_SVG.
Dashboard Helm Values
packages/system/dashboard/values.yaml
Updated image digests for openapiUI and openapiUIK8sBff; changed tokenProxy tag from v0.37.0 to latest with corresponding digest.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • API endpoint migration: Verify the namespace endpoint change (/api/v1/namespaces → /apis/core.cozystack.io/v1alpha1/tenantnamespaces) is consistently applied across all affected components (ListInsideClusterAndNs, useNavSelectorInside, getBacklink, prepareFormProps)
  • Resource fetching refactor: Validate that useApiResources is correctly configured with the new API group (core.cozystack.io), version (v1alpha1), and resource name (tenantnamespaces) parameters
  • Form handling logic in additionalProperties: Complex changes to field type inference, nested property resolution, and value normalization in FormObjectFromSwagger, casts, and utils warrant careful verification of edge cases
  • Config key naming consistency: Ensure all references to CUSTOM_TENANT_TEXT and CUSTOM_LOGO_SVG are updated across templates, deployments, and consuming components to prevent runtime failures

Possibly related PRs

Suggested reviewers

  • lllamnyp
  • nbykov0

Poem

🐰 A rabbit hops through config trees,
New namespaces flow with ease,
API patches heal the forms,
Custom branding's the new norm,
Builds are swift, no git delays—
Updates bloom in modern ways! 🌿

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[dashboard] Migrate patches to upstream project' accurately reflects the main objective: moving patches from this repository to the upstream openapi-ui and openapi-ui-k8s-bff projects.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dashboard-patches

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

[dashboard] Fix nested lists in addtiionalProperties

Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps Andrei Kvapil (kvaps) added the kind/backport Categorizes issue or PR as requiring a backport to the current release line label Nov 4, 2025
@kvaps
Andrei Kvapil (kvaps) marked this pull request as ready for review November 4, 2025 12:59
@dosubot dosubot Bot added the size/L This PR changes 100-499 lines, ignoring generated files label Nov 4, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1d10907 and 723eefe.

📒 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/Dockerfile
  • packages/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

Comment on lines +14 to +43
+ 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
+ }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
+ 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.

@kvaps
Andrei Kvapil (kvaps) merged commit ab5101a into main Nov 4, 2025
22 checks passed
@kvaps
Andrei Kvapil (kvaps) deleted the dashboard-patches branch November 4, 2025 16:12
@github-actions

github-actions Bot commented Nov 4, 2025

Copy link
Copy Markdown

Backport failed for release-0.37, because it was unable to cherry-pick the commit(s).

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

@coderabbitai coderabbitai Bot mentioned this pull request Nov 25, 2025
Aleksei Sviridkin (lexfrei) added a commit that referenced this pull request Sep 18, 2026
…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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/backport Categorizes issue or PR as requiring a backport to the current release line size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant