Rewrite resourcesPreset values in every apps/* and extras/* chart from
the legacy flat names to the new instance-type form, using the 1:1
mapping:
nano -> t1.nano micro -> t1.micro
small -> t1.small medium -> c1.small
large -> c1.medium xlarge -> c1.large
2xlarge -> c1.xlarge
Each affected values.yaml carries the canonical 47-value enum (40
instance-type names plus 7 legacy aliases) so the schema accepts both
forms during the deprecation window. cozyvalues-gen regenerates the
matching api/apps/v1alpha1/*/types.go kubebuilder enum and defaults,
the chart values.schema.json, the README parameter table, and the
ApplicationDefinition openAPISchema in packages/system/*-rd/cozyrds.
Three hardcoded legacy literals in chart templates migrated:
- packages/apps/harbor/templates/harbor.yaml:121 (portal)
- packages/apps/opensearch/templates/opensearch.yaml:43 (dashboards)
- packages/system/keycloak/templates/sts.yaml:115 (heap fallback)
packages/apps/foundationdb/Makefile gains the missing hack/update-crd.sh
call. Without it, every regen left foundationdb-rd cozyrds stale and
new FoundationDB app CRs through cozystack-api were rejected at
validation for any non-legacy resourcesPreset value.
Every default-rendered chart produces identical CPU and memory to the
value applied before the rename, courtesy of the legacy alias table in
cozy-lib and the 1:1 default mapping.
Co-authored-by: Matthieu ROBIN <matthieu@hidora.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
## What this PR does
Fixes#2514.
When `external: true` is set on a non-sharded `MongoDB`, Cozystack
rendered a single
`LoadBalancer` Service whose selector matched **all** replica-set
members
(`app.kubernetes.io/replset: rs0`). Round-robin balancing sent ~⅔ of
writes to
secondaries and they were rejected with `MongoServerError: not primary`.
Drivers couldn't recover on their own either: connecting through the LB
returned
the in-cluster DNS names of all members from `isMaster`, none of which
resolve
from outside the cluster, so automatic primary discovery failed.
This PR replaces the manual `external-svc.yaml` (for replica-set mode)
with the
Percona MongoDB operator's native `replsets[].expose` feature:
```yaml
replsets:
- name: rs0
expose:
enabled: true
type: LoadBalancer
externalTrafficPolicy: Local
```
The operator then:
- creates one `LoadBalancer` Service **per pod** (`<release>-rs0-0`,
`-1`, `-2`)
with `statefulset.kubernetes.io/pod-name` selectors,
- watches `Service.status.loadBalancer.ingress` for each pod and
rewrites the
member `host` in `rs.conf` to the external IPs.
External clients use a standard replica-set URI
(`mongodb://...:27017,...:27017,...:27017/?replicaSet=rs0`) and the
driver
discovers the primary correctly from outside the cluster.
For **sharded** mode the existing single `LoadBalancer` is preserved —
it
front-ends stateless `mongos`, which can route writes to the right shard
primary itself. `external-svc.yaml` is now scoped to that case only.
### Tested
- `helm unittest .` in `packages/apps/mongodb/`: 91/91 pass.
- Applied on a dev stand:
- `replsets[0].expose` is set as expected in the rendered PSMDB CR.
- The Percona operator (`v1.21.1`) accepts the spec and creates 3
per-pod
`LoadBalancer` Services with `statefulset.kubernetes.io/pod-name`
selectors. The previous single round-robin Service is no longer
rendered.
- With an LB IP pool present, the operator promotes the allocated LB IPs
into
the PSMDB `status.host` field and into `rs.conf`.
End-to-end mongosh write loop wasn't run on the dev stand because the
underlying network does not advertise/route allocated LoadBalancer IPs
(no
working L2/BGP path), so the rewritten `rs.conf` members are unreachable
in
that environment. The structural change is otherwise fully verified and
the
issue's reproduction scenario expects a real LB-capable network.
### Release note
```release-note
fix(mongodb): expose each replica-set member through its own LoadBalancer when `external: true`, so external clients can discover the primary via the standard replica-set connection string and writes no longer fail with "not primary" errors.
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* External LoadBalancer services now only render when both external and
sharding are enabled.
* Replica set external exposure is now conditional based on the external
setting.
* Service configuration now uses LoadBalancer type with Local traffic
policy for external access.
* Service selectors refined for proper mongos targeting in sharded
deployments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Describe the in-place password rotation performed by the Percona operator
when upgrading to releases that scope the system users secret per CR.
Clarify that consumers of the credentials secret need a pod restart to
pick up the new password, custom user secrets are unaffected, and the
legacy namespace-shared secret is left orphaned and must be cleaned up
manually.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Update Data lifecycle section to address review feedback:
- Reflect the release-scoped users secret naming.
- Distinguish operator-driven PVC release from actual PV/data
deletion (depends on StorageClass reclaimPolicy).
- Document that TLS secrets (<release>-ssl, <release>-ssl-internal)
are not reclaimed automatically.
- Add a recovery note for the case where the operator is removed
before the CR, leaving finalizers unable to run.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Test descriptions said 'percona.com/delete-psmdb-pvc finalizer'
while the assertions verified both delete-psmdb-pvc and
delete-psmdb-pods-in-order. Use 'Percona finalizers' to match
what the tests actually check.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
The operator deletes spec.secrets.users (defaulted to the global
percona-server-mongodb-users) as part of the delete-psmdb-pvc
finalizer flow. With the default value, deleting one MongoDB
release in a namespace would remove the secret shared with any
other MongoDB release there.
Override spec.secrets.users with a release-scoped name so each
release owns its own secret and uninstalls do not collide.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
The previous wording listed only one operator-managed secret with
'e.g.' prefix. The Percona Operator finalizer flow actually deletes
four specific secrets (internal-<release>, internal-<release>-users,
<release>-mongodb-encryption-key, and the global default
percona-server-mongodb-users). Document each by name so operators
understand the full deletion blast radius, especially the global
default which can collide with externally-created secrets sharing
the same name.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Distinguish between operator-managed secrets reclaimed via the
finalizer flow (e.g. internal-*-users) and Helm-managed secrets
(credentials, user secrets, s3 backup creds) removed by helm
uninstall. The previous wording was ambiguous and could mislead
users about which cleanup path applies to which secret.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
PerconaServerMongoDB CR now carries the upstream-default finalizer
pair: percona.com/delete-psmdb-pods-in-order ensures primary-last
graceful shutdown before percona.com/delete-psmdb-pvc reclaims
storage. This matches deploy/cr.yaml defaults in operator v1.21.1
and prevents potential data loss on deletion under load.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Upstream Percona Operator v1.21.1 ships both delete-psmdb-pvc and
delete-psmdb-pods-in-order in deploy/cr.yaml by default. The
pods-in-order finalizer ensures primary-last graceful shutdown,
preventing data loss on cluster deletion under load.
Currently fails — establishes red phase before adding the finalizer.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Replace the equal assertion (which would block adding more finalizers)
with a sharded-mode test case ensuring the finalizer is rendered
regardless of replicaset/sharded configuration.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Document that uninstalling the release reclaims PVCs and
operator-managed user secrets via the percona.com/delete-psmdb-pvc
finalizer. Pre-existing users who relied on orphaned PVCs to
recover data should take backups before uninstalling.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Rename test description to accurately reflect what's verified
(template renders the finalizer, not runtime cleanup behavior).
Add equal assertion locking the exact finalizer list to catch
regressions where a stray finalizer is appended.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
Add helm-unittest assertion verifying that the rendered
PerconaServerMongoDB CR carries percona.com/delete-psmdb-pvc finalizer.
Currently fails — establishes red phase before adding the fix.
Signed-off-by: Arsolitt <arsolitt@gmail.com>
A single LoadBalancer selecting all replset members round-robined writes
across primary and secondaries, so ~⅔ of writes failed with "not primary".
Drivers couldn't auto-recover either: `isMaster` returned in-cluster DNS
names that don't resolve from outside.
Switch to the Percona operator's native `replsets[].expose` so it creates
one LoadBalancer per pod and rewrites `rs.conf` with the external IPs;
the driver then discovers the primary correctly via the standard replica
set connection string. The manual `external-svc.yaml` is now scoped to
sharded mode (mongos front-end) only.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Replace the old MongoDB logo with the official one featuring
the MongoDB leaf icon on a green radial gradient background.
Co-authored-by: Viktoriia Kvapil <159528100+kvapsova@users.noreply.github.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Add migration script to convert existing MongoDB HelmReleases
from old users format to new users + databases format.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Align MongoDB configuration with postgres and mysql patterns:
- Add separate `databases` section with `roles.admin` and `roles.readonly`
- Simplify `users` to only contain optional password field
- All users now authenticate via `admin` database (MongoDB best practice)
- Admin role maps to readWrite + dbAdmin permissions
- Readonly role maps to read permission
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Remove the ability for users to specify custom container images
(images.pmm and images.backup) in the MongoDB application values.
This is a security hardening measure - allowing users to specify
arbitrary container images could lead to running malicious or
compromised images, supply chain attacks, or privilege escalation.
The images are now hardcoded in the template:
- percona/pmm-client:2.44.1
- percona/percona-backup-mongodb:2.11.0
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Add MongoDB managed service based on Percona Operator for MongoDB with:
- Replica set mode (default) and sharded cluster mode
- Configurable replicas, storage, and resource presets
- Custom users with role-based access control
- S3-compatible backup with PITR support
- Bootstrap/restore from backup
- External access support
- WorkloadMonitor integration for dashboard
- Comprehensive helm-unittest test coverage (91 tests)
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>