ClusterIssuer solver referenced IngressClass "nginx" which does not
exist on cozystack clusters — real classes are named after tenant
namespaces (e.g. tenant-root). Cert issuance only worked because every
requesting Ingress overrode the ClusterIssuer via the legacy
acme.cert-manager.io/http01-ingress-class annotation.
Switch both sides to the modern cert-manager API (available since
cert-manager 1.12; cozystack ships 1.19.3):
- ClusterIssuer: http01.ingress.ingressClassName, value parameterized
from _cluster.expose-ingress (default "tenant-root")
- Ingress annotation: http01-ingress-ingressclassname
These must migrate together — mixing ingressClassName (ClusterIssuer)
with the old http01-ingress-class annotation triggers cert-manager's
"fields ingressClassName and class cannot be set at the same time"
validation and breaks issuance.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 2b6e20cc3f)
Update fix-duplicate-tcp-ports patch to preserve existing TCP ports when
DrbdRscData is recreated during toggle-disk operations. Without this,
removeLayerData() frees ports and ensureStackDataExists() may allocate
different ones, causing port mismatches between controller and satellites
if the satellite misses the update.
Also add dh_strip_nondeterminism override in Dockerfile to fix build
failures on some JAR files.
Upstream: https://github.com/LINBIT/linstor-server/pull/476#issuecomment-4147527442
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 812d4138bb)
Dashboard requests EndpointSlices from discovery.k8s.io API group
to display "Pod serving" section on Service details page. Without
this permission, tenant users see a 403 error.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit ab92b67c3f)
The dashboard UI fetches StorageClasses via the Kubernetes API to populate
dropdowns (e.g. in the Postgres form), but the cozystack-dashboard-readonly
ClusterRole did not include storage.k8s.io/storageclasses. This caused
authenticated users to see "Error" instead of the StorageClass name.
Add get/list/watch permissions for storageclasses to the dashboard readonly
role, consistent with the existing backupclasses entry.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit a7a80a7628)
The cozy:tenant:admin:base ClusterRole was missing several application
resources from apps.cozystack.io, preventing tenant admins from creating
them (the "Add" button was inactive in the dashboard).
Add the following resources: foundationdbs, harbors, mongodbs, openbaos,
opensearches, qdrants, vpns.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit 8e01eb5f7e)
Add secret-hash annotation to the dashboard KeycloakClient CRD resource
so that when the Kubernetes Secret value changes, the operator detects
the CRD update and reconciles the client secret in Keycloak.
Without this annotation, if the dashboard-client Secret is recreated
with a new value (e.g. after upgrade), the KeycloakClient spec remains
unchanged, the operator skips reconciliation, and Keycloak retains the
stale secret — causing authentication failures for the dashboard.
Assisted-By: Claude AI
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
(cherry picked from commit bb5ee3ea4a)
The deployment template was constructing the S3 endpoint from the tenant's
namespace host (e.g. s3.freedom.infra.example.com), while COSI credentials
are issued for the actual SeaweedFS endpoint (e.g. s3.infra.example.com).
This mismatch caused 'invalid credentials' errors when users tried to log
in with valid credentials from the bucket secret.
Now the endpoint is resolved from BucketInfo (same source as credentials),
with a fallback to the constructed namespace host for first-time deploys
before BucketAccess secrets are created.
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
(cherry picked from commit f647cfd7b9)
The gcr.io/kubebuilder/kube-rbac-proxy image is no longer available
since GCR was deprecated. Replace it with quay.io/brancz/kube-rbac-proxy
from the original upstream author.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 4946383cf1)
Use a startupProbe to defer liveness/readiness checks until Keycloak
has fully started, instead of relying on initialDelaySeconds. This is
more robust for applications with variable startup times.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
(cherry picked from commit d18ed79382)
Keycloak 26.x exposes dedicated health endpoints on the management
port (9000) via /health/live and /health/ready. The previous probes
used GET / on port 8080 which redirects to the configured KC_HOSTNAME
(HTTPS), causing kubelet to fail the probe with "Probe terminated
redirects" and eventually kill the pod in a crashloop.
Changes:
- Add KC_HEALTH_ENABLED=true to activate health endpoints
- Expose management port 9000 in container ports
- Switch liveness probe to /health/live on port 9000
- Switch readiness probe to /health/ready on port 9000
- Increase failure thresholds for more tolerance during startup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: mattia-eleuteri <mattia@hidora.io>
(cherry picked from commit 0873691913)
## What this PR does
Combines and unifies COSI enhancements across seaweedfs and bucket
charts:
**SeaweedFS (extra + system charts):**
- Rename storage pool BucketClass suffix from `-worm` to `-lock`
- Rename parameter `disk` to `diskType` for consistency with COSI driver
- Reduce default object lock retention from 36500 to 365 days
- Add `-lock` BucketClass (COMPLIANCE mode, 365 days) for client and
system topologies
- Add `-readonly` BucketAccessClass with explicit `accessPolicy` for all
topologies
- Add explicit `accessPolicy: readwrite` on default BucketAccessClass
- Update pool name validation to reject `-lock` suffix (was `-worm`)
**Bucket app:**
- Add `locking` parameter: provisions from `-lock` BucketClass
- Add `storagePool` parameter: selects pool-specific BucketClass
- Replace hardcoded BucketAccess with `users` map — each entry creates a
BucketAccess with optional `readonly` flag
- Update dashboard RBAC to dynamically list user credential secrets
- Update ApplicationDefinition schema with new properties
**Breaking change:** empty `users: {}` (default) produces zero
BucketAccess resources. Existing buckets that relied on the implicit
default BucketAccess will need to define users explicitly.
### Release note
```release-note
[apps] Add locking, storagePool, and users configuration to bucket app; rename COSI BucketClass suffix from -worm to -lock
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Bucket locking with a shorter retention option, storage-pool
selectable bucket classes, and per-user access (per-user BucketAccess
and readonly controls)
* S3 Manager login mode: user login/logout, per-session credentials, and
new login UI
* **Behavior Changes**
* Credential handling changed to per-user secrets/label selection;
previously generated secrets removed; Ingress basic auth annotations
removed
* **Documentation**
* Added parameters: locking, storagePool, users (including per-user
readonly)
* **Updates**
* Updated COSI driver and S3 manager images
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Add mongodb/mongodb-overview and mongodb/mongodb-inmemory entries
to the monitoring dashboards list so GrafanaDashboard CRDs are
generated and dashboards are served by the grafana-dashboards
HTTP service.
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
v0.1.2 ignores accessPolicy parameter from BucketAccessClass,
granting readwrite access to all users regardless of the
readonly flag. v0.3.0 includes support for readonly bucket
access, Object Lock, and improved error handling.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Rebuild s3manager with auth.go login page support and push
to 999669/s3manager registry for testing.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Remove nginx basic auth and credential secret injection from the
bucket Helm chart. s3manager now always starts in login mode and
handles authentication via its own login page with encrypted
session cookies. This eliminates the dependency on the -credentials
and -ui-auth secrets for the UI layer.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
deployment.yaml: use s3._namespace.host for ENDPOINT instead of
secret ref, inject ACCESS_KEY_ID/SECRET_ACCESS_KEY only when users
exist. Without users, s3manager starts in login mode.
ingress.yaml: nginx basic auth annotations only when users exist.
Without users, s3manager handles authentication via its login form.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
When a bucket has no users configured, s3manager previously crashed
due to missing ACCESS_KEY_ID/SECRET_ACCESS_KEY env vars. This adds
a login mode where users enter their S3 credentials via a web form.
New Go code (via cozystack.patch):
- auth.go: session-based auth middleware, login/logout handlers,
per-request S3 client from encrypted cookie session
- login.html.tmpl: Materialize CSS login form
- main.go: LoginMode toggle, conditional route setup
- Dependency: gorilla/sessions for AES-256 encrypted cookies
Dockerfile: add go mod tidy step for new dependency resolution.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
The default BucketAccess was removed in favor of per-user access.
Update secret.yaml to look up the first user's COSI secret instead
of the non-existent default one, with nil-check for race conditions.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Remove the yq strip of properties from Makefile that was clearing
the schema, and run make generate to sync all generated files.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Create labeled secrets in the -system chart using lookup to copy
credentials from COSI-created secrets. The ApplicationDefinition
matchLabels selector exposes them in the dashboard.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Add a catch-all include selector so that COSI-created user credential
secrets (dynamically named per user) are visible in the dashboard.
The lineage webhook already verifies ownership via the graph walk
(Secret -> BucketAccess -> HelmRelease -> Bucket), so an empty selector
safely matches only secrets belonging to this application.
This is needed because COSI sidecar creates secrets without custom
labels, making the matchLabels pattern (used by rabbitmq) inapplicable.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
Add COSI resources for object locking and read-only access to both
client topology and system chart:
- BucketClass with -lock suffix (COMPLIANCE mode, 365 days retention)
- BucketAccessClass with -readonly suffix
- Explicit accessPolicy: readwrite on default BucketAccessClass
Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
## What this PR does
Updates the openapi-k8s-toolkit integration in the dashboard to fix two
UX issues:
**1. Allow clearing the instanceType field in VMInstance form**
When `instanceType` has a default value, clearing the field in the form
UI would
silently revert to the default, making it impossible to explicitly send
an empty
value. This blocked use of custom KubeVirt resources without a named
instance type.
Adds `allowEmpty: true` to the instanceType listInput field so the BFF
preserves
an explicit empty value. Also introduces a generic `persistType` prop
(`'str' | 'number' | 'arr' | 'obj'`) to the listInput component, so the
allow-empty behaviour works correctly for any field type, not just
strings.
Updates openapi-k8s-toolkit to release/1.4.0 (d6b9e4ad), which already
includes
the FormListInput layout refactor — the previous
formlistinput-value-binding.diff
patch is no longer needed.
Upstream PR:
https://github.com/PRO-Robotech/openapi-k8s-toolkit/pull/340
**2. Preserve newlines when copying secrets with CMD+C**
Native `input[type=text]` strips newlines on copy. Adds an `onCopy`
handler to
the SecretBase64Plain component that intercepts the copy event and
writes the full
decoded value (including newlines) to the clipboard.
Upstream PR:
https://github.com/PRO-Robotech/openapi-k8s-toolkit/pull/339
### Release note
```release-note
[dashboard] Fix clearing instanceType in VMInstance form: explicit empty value
is now correctly sent to the API instead of falling back to the schema default.
Fix CMD+C copying of secrets stripping newlines.
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Dropdown fields now support configuration to allow empty selections
* Enhanced empty value handling for form fields across multiple data
types (string, number, array, object)
* **Bug Fixes**
* Fixed secret field copy functionality to preserve plain-text format
when visible
* **Chores**
* Updated base image dependencies for dashboard build
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What this PR does
Replace deprecated `KC_PROXY=edge` with `KC_PROXY_HEADERS=xforwarded`
and `KC_HTTP_ENABLED=true` in the Keycloak StatefulSet template.
`KC_PROXY` was removed in Keycloak 26.x, causing "Non-secure context
detected" warnings and broken cookie handling when running behind a
reverse proxy with TLS termination.
### Release note
```release-note
[system] Fix Keycloak proxy headers configuration for compatibility with Keycloak 26.x
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Updated system configuration to improve proxy header handling and
enable direct HTTP support for enhanced compatibility with reverse proxy
environments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Update openapi-k8s-toolkit commit to d6b9e4ad (release/1.4.0) which
includes the FormListInput layout refactor, making formlistinput-value-binding.diff
obsolete.
Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
Update openapi-k8s-toolkit to release/1.4.0 (d6b9e4ad). The previous
value-binding layout refactor is already included upstream, so drop the
formlistinput-value-binding.diff patch.
Add formlistinput-allow-empty.diff patch which introduces two props to
the listInput component:
- allowEmpty: when set, auto-persists the field so BFF sends an empty
value instead of falling back to the schema default
- persistType: controls the type of empty value ('str' | 'number' | 'arr'
| 'obj'), allowing the feature to work correctly for any field type
Set allowEmpty: true on the VMInstance instanceType field so users can
explicitly clear the selection and override the default instance type.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->
## What this PR does
### Release note
<!-- Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->
```release-note
Disabled private key rotation in every CA cert in cozystack system packages to prevent trustchain problems when CA cert reissued
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Disabled private-key rotation (set rotationPolicy: Never) for CA/root
certificates used by multiple system components (ingress-nginx, linstor,
linstor-scheduler, seaweedfs, victoria-metrics-operator,
kubeovn-webhook, lineage-controller-webhook, cozystack-api, etcd,
linstor API/internal, seaweedfs).
* Added patch application steps to relevant update workflows to ensure
the certificate template changes are applied during chart/update
operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
KC_PROXY=edge was deprecated and removed in Keycloak 26.x, causing
"Non-secure context detected" warnings and broken cookie handling
behind reverse proxy. Replace with KC_PROXY_HEADERS=xforwarded and
KC_HTTP_ENABLED=true.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
The dashboard BFF service account (incloud-web-web) falls under the
default "service-accounts" FlowSchema which maps to the "workload-low"
priority level. Under load, this causes API Priority and Fairness to
return 429 (Too Many Requests) responses to the BFF, resulting in 500
errors for dashboard users.
Add a FlowSchema that maps the BFF service account to the "exempt"
priority level to prevent APF throttling of dashboard API requests.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>