From 9391bfc520c55ff66c1547561bd3189dd911c8cb Mon Sep 17 00:00:00 2001 From: Ashley Cui Date: Tue, 2 Mar 2021 16:14:10 -0500 Subject: [PATCH] Add version field to secret compat list/inspect api Docker api expects secrets endpoint to have a version field. So, the version field is added into the compat endpoint only. The version field is always 1, since Docker uses the version to keep track of updates to the secret, and currently we cannot update a secret. Signed-off-by: Ashley Cui --- pkg/api/handlers/compat/secrets.go | 32 ++++++++++++++++++++++++++++-- pkg/api/server/register_secrets.go | 4 ++-- pkg/domain/entities/secrets.go | 23 +++++++++++++++++++++ test/apiv2/50-secrets.at | 11 ++++++---- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/pkg/api/handlers/compat/secrets.go b/pkg/api/handlers/compat/secrets.go index c5ee8c324b..86e3887a4f 100644 --- a/pkg/api/handlers/compat/secrets.go +++ b/pkg/api/handlers/compat/secrets.go @@ -40,7 +40,21 @@ func ListSecrets(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } - utils.WriteResponse(w, http.StatusOK, reports) + if utils.IsLibpodRequest(r) { + utils.WriteResponse(w, http.StatusOK, reports) + return + } + // Docker compat expects a version field that increments when the secret is updated + // We currently can't update a secret, so we default the version to 1 + compatReports := make([]entities.SecretInfoReportCompat, 0, len(reports)) + for _, report := range reports { + compatRep := entities.SecretInfoReportCompat{ + SecretInfoReport: *report, + Version: entities.SecretVersion{Index: 1}, + } + compatReports = append(compatReports, compatRep) + } + utils.WriteResponse(w, http.StatusOK, compatReports) } func InspectSecret(w http.ResponseWriter, r *http.Request) { @@ -59,7 +73,21 @@ func InspectSecret(w http.ResponseWriter, r *http.Request) { utils.SecretNotFound(w, name, errs[0]) return } - utils.WriteResponse(w, http.StatusOK, reports[0]) + if len(reports) < 1 { + utils.InternalServerError(w, err) + return + } + if utils.IsLibpodRequest(r) { + utils.WriteResponse(w, http.StatusOK, reports[0]) + return + } + // Docker compat expects a version field that increments when the secret is updated + // We currently can't update a secret, so we default the version to 1 + compatReport := entities.SecretInfoReportCompat{ + SecretInfoReport: *reports[0], + Version: entities.SecretVersion{Index: 1}, + } + utils.WriteResponse(w, http.StatusOK, compatReport) } func RemoveSecret(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index 1c5f5954b6..531623845b 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -115,7 +115,7 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // parameters: // responses: // '200': - // "$ref": "#/responses/SecretListResponse" + // "$ref": "#/responses/SecretListCompatResponse" // '500': // "$ref": "#/responses/InternalError" r.Handle(VersionedPath("/secrets"), s.APIHandler(compat.ListSecrets)).Methods(http.MethodGet) @@ -158,7 +158,7 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // "$ref": "#/responses/SecretInspectResponse" + // "$ref": "#/responses/SecretInspectCompatResponse" // '404': // "$ref": "#/responses/NoSuchSecret" // '500': diff --git a/pkg/domain/entities/secrets.go b/pkg/domain/entities/secrets.go index 3481cbe058..8ede981da0 100644 --- a/pkg/domain/entities/secrets.go +++ b/pkg/domain/entities/secrets.go @@ -42,6 +42,15 @@ type SecretInfoReport struct { Spec SecretSpec } +type SecretInfoReportCompat struct { + SecretInfoReport + Version SecretVersion +} + +type SecretVersion struct { + Index int +} + type SecretSpec struct { Name string Driver SecretDriverSpec @@ -78,6 +87,13 @@ type SwagSecretListResponse struct { Body []*SecretInfoReport } +// Secret list response +// swagger:response SecretListCompatResponse +type SwagSecretListCompatResponse struct { + // in:body + Body []*SecretInfoReportCompat +} + // Secret inspect response // swagger:response SecretInspectResponse type SwagSecretInspectResponse struct { @@ -85,6 +101,13 @@ type SwagSecretInspectResponse struct { Body SecretInfoReport } +// Secret inspect compat +// swagger:response SecretInspectCompatResponse +type SwagSecretInspectCompatResponse struct { + // in:body + Body SecretInfoReportCompat +} + // No such secret // swagger:response NoSuchSecret type SwagErrNoSuchSecret struct { diff --git a/test/apiv2/50-secrets.at b/test/apiv2/50-secrets.at index 69e1f3ae97..c4ffb5883e 100644 --- a/test/apiv2/50-secrets.at +++ b/test/apiv2/50-secrets.at @@ -14,15 +14,18 @@ t POST secrets/create '"Name":"mysecret","Data":"c2VjcmV0","Labels":{"fail":"fai t POST secrets/create '"Name":"mysecret","Data":"c2VjcmV0"' 409 # secret inspect -t GET secrets/mysecret 200\ - .Spec.Name=mysecret +t GET secrets/mysecret 200 \ + .Spec.Name=mysecret \ + .Version.Index=1 # secret inspect non-existent secret t GET secrets/bogus 404 # secret list -t GET secrets 200\ - length=1 +t GET secrets 200 \ + length=1 \ + .[0].Spec.Name=mysecret \ + .[0].Version.Index=1 # secret list unsupported filters t GET secrets?filters='{"name":["foo1"]}' 400