Existence checks depend on MinIO error codes; decide policy/user existence from list calls instead

Abierto
#144 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
72/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
go
Área
api, backend

Línea de trabajo

Start in internal/s3/client/impl/minioS3Client.go at GetPolicyInfo, UserExist, and DeleteUser, then read the surrounding MinIO client methods and their callers. Trace the list operations proposed for policies and users, preserving list errors, and verify that missing objects can be created or treated as already deleted without relying on MinIO-specific error codes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

The MinIO client decides whether a policy or user exists by matching MinIO-specific error codes. Any backend that implements the MinIO admin API but reports "not found" differently can never get a Policy or S3User created. Its CRs are requeued indefinitely.

We hit this with RustFS (s3Provider: minio): Bucket CRs reconcile, Policy and S3User never do. The root cause is not RustFS-specific. The client depends on error nomenclature, as the code comment itself notes: "Not ideal (breaks if error nomenclature changes)".

Why this matters now: MinIO community edition is no longer maintained

  • minio/minio, minio/mc and minio/operator are archived on GitHub. The minio/minio README states "THIS REPOSITORY IS NO LONGER MAINTAINED" and points to the proprietary AIStor editions.
  • The images are gone from Docker Hub (minio/minio → 404), and quay.io/minio/minio now requires authentication (401).
  • The last public server image is RELEASE.2025-09-07T16-13-09Z. The fix for CVE-2025-62506 (RELEASE.2025-10-15T17-29-55Z) exists only as source.

Many s3-operator users will move off MinIO to other self-hosted S3 servers. Where the new server implements the MinIO admin API (RustFS does), they can keep s3Provider: minio, but only if the client stops relying on MinIO's exact error nomenclature. Making the existence checks backend-neutral keeps the minio provider useful after MinIO itself is gone.

Where

internal/s3/client/impl/minioS3Client.go (commit 54d5781):

  • GetPolicyInfo (L341): madmin.ToErrorResponse(err).Code == "XMinioAdminNoSuchPolicy"
  • UserExist (L425) and DeleteUser (L440): ... == "XMinioAdminNoSuchUser"

With madmin-go/v4 the HTTP status is not kept in ErrorResponse, so status-based detection isn't an option either.

What a missing object returns (measured with madmin-go/v4 v4.10.0, the version in go.mod):

Call on a missing object MinIO RELEASE.2025-09-07 RustFS 1.0.0
InfoCannedPolicy 404 XMinioAdminNoSuchPolicy 500 InternalError "policy does not exist"
GetUserInfo 404 XMinioAdminNoSuchUser 404 NoSuchResource
RemoveUser 404 XMinioAdminNoSuchUser 500 InternalError "…user '…' does not exist"

The two RustFS 500s are reported upstream in https://github.com/rustfs/rustfs/issues/8117. Even once they are fixed, RustFS's not-found code is NoSuchResource, not XMinioAdmin*.

Proposal: decide existence from list calls, not from error codes (happy to send a PR)

  • PolicyExist(name) → ListCannedPolicies() and look up name. Call InfoCannedPolicy only for policies known to exist.
  • UserExist(accessKey) → ListUsers() and look up accessKey.
  • DeleteUser(accessKey) → remove only if the user is listed; otherwise treat it as already deleted.
  • Any error from the list calls themselves stays a real error.

This removes the dependency on error nomenclature entirely. I checked the same sequence on both backends with madmin-go/v4 v4.10.0:

  • list (absent) → add → list (present) → info → remove → list (absent)

Both ListCannedPolicies and ListUsers reflect creation and removal immediately, on MinIO and on RustFS 1.0.0. This works on RustFS today, including the 500 cases above.

The cost is one list call per reconcile of a Policy / S3User. That is fine for the usual number of identities per instance. A short-lived cache could be added later if needed.

The current code-based checks could stay as a fast path where the code is recognised, with the list call as the fallback. The list is the source of truth either way.

Reproduce

  1. Deploy RustFS 1.0.0.
  2. Create an S3Instance with s3Provider: minio pointing at it.
  3. Apply a Policy and an S3User.
  4. The operator logs an error occurred while checking policy existence / an error occurred when checking user's existence, and requeues indefinitely.

A policy created by hand beforehand does reconcile, and the operator updates it. Only creation (and user deletion) is blocked.

Environment

  • inseefrlab/s3-operator:v0.12.0 (code at main 54d5781 has the same checks)
  • RustFS rustfs/rustfs:1.0.0, on k3d (k3s v1.30); MinIO RELEASE.2025-09-07T16-13-09Z for comparison
Lenguaje dominante
Go
Estrellas
66
Forks
16
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

  • Incluye un Dockerfile o un archivo de Docker Compose
  • Sin plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de InseeFrLab/s3-operator

Todos los issues de InseeFrLab/s3-operator

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.