diff --git a/CHANGELOG.md b/CHANGELOG.md index 4045db9df49..b39b9bf153e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ This release adds an embedded SQLite database for storing metadata required by t 1. [21828](https://github.com/influxdata/influxdb/pull/21828): Added the command `influx inspect verify-wal`. 1. [21814](https://github.com/influxdata/influxdb/pull/21814): Ported the `influxd inspect report-tsm` command from 1.x. 1. [21910](https://github.com/influxdata/influxdb/pull/21910): Added `--ui-disabled` option to `influxd` to allow for running with the UI disabled. +1. [21938](https://github.com/influxdata/influxdb/pull/21938): Added route to delete individual secret. ### Bug Fixes diff --git a/secret/http_server.go b/secret/http_server.go index 08f6d990bf1..bfb081f1aa5 100644 --- a/secret/http_server.go +++ b/secret/http_server.go @@ -35,8 +35,8 @@ func NewHandler(log *zap.Logger, idLookupKey string, svc influxdb.SecretService) r.Get("/", h.handleGetSecrets) r.Patch("/", h.handlePatchSecrets) - // TODO: this shouldn't be a post to delete - r.Post("/delete", h.handleDeleteSecrets) + r.Delete("/{secretID}", h.handleDeleteSecret) + r.Post("/delete", h.handleDeleteSecrets) // deprecated return r } @@ -99,7 +99,8 @@ type secretsDeleteBody struct { Secrets []string `json:"secrets"` } -// handleDeleteSecrets is the HTTP handler for the DELETE /api/v2/orgs/:id/secrets route. +// handleDeleteSecrets is the HTTP handler for the POST /api/v2/orgs/:id/secrets/delete route. +// deprecated. func (h *handler) handleDeleteSecrets(w http.ResponseWriter, r *http.Request) { orgID, err := h.decodeOrgID(r) if err != nil { @@ -121,6 +122,21 @@ func (h *handler) handleDeleteSecrets(w http.ResponseWriter, r *http.Request) { h.api.Respond(w, r, http.StatusNoContent, nil) } +// handleDeleteSecret is the HTTP handler for the DELETE /api/v2/orgs/:id/secrets/:id route. +func (h *handler) handleDeleteSecret(w http.ResponseWriter, r *http.Request) { + orgID, err := h.decodeOrgID(r) + if err != nil { + h.api.Err(w, r, err) + } + + if err := h.svc.DeleteSecret(r.Context(), orgID, chi.URLParam(r, "secretID")); err != nil { + h.api.Err(w, r, err) + return + } + + h.api.Respond(w, r, http.StatusNoContent, nil) +} + func (h *handler) decodeOrgID(r *http.Request) (platform.ID, error) { org := chi.URLParam(r, h.idLookupKey) if org == "" { diff --git a/secret/http_server_test.go b/secret/http_server_test.go index ed20e1a451c..e5414fb63a5 100644 --- a/secret/http_server_test.go +++ b/secret/http_server_test.go @@ -342,3 +342,74 @@ func TestSecretService_handleDeleteSecrets(t *testing.T) { }) } } + +func TestSecretService_handleDeleteSecret(t *testing.T) { + type fields struct { + SecretService influxdb.SecretService + } + type args struct { + orgID platform.ID + secretID string + } + type wants struct { + statusCode int + contentType string + body string + } + + tests := []struct { + name string + fields fields + args args + wants wants + }{ + { + name: "delete secret", + fields: fields{ + &mock.SecretService{ + DeleteSecretFn: func(ctx context.Context, orgID platform.ID, s ...string) error { + return nil + }, + }, + }, + args: args{ + orgID: 1, + secretID: "abc", + }, + wants: wants{ + statusCode: http.StatusNoContent, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := NewHandler(zaptest.NewLogger(t), "id", tt.fields.SecretService) + router := chi.NewRouter() + router.Mount("/api/v2/orgs/{id}/secrets", h) + + u := fmt.Sprintf("http://any.url/api/v2/orgs/%s/secrets/%s", tt.args.orgID, tt.args.secretID) + r := httptest.NewRequest("DELETE", u, nil) + w := httptest.NewRecorder() + + router.ServeHTTP(w, r) + + res := w.Result() + content := res.Header.Get("Content-Type") + body, _ := ioutil.ReadAll(res.Body) + + if res.StatusCode != tt.wants.statusCode { + t.Errorf("handleDeleteSecrets() = %v, want %v", res.StatusCode, tt.wants.statusCode) + } + if tt.wants.contentType != "" && content != tt.wants.contentType { + t.Errorf("handleDeleteSecrets() = %v, want %v", content, tt.wants.contentType) + } + if tt.wants.body != "" { + if string(body) != tt.wants.body { + t.Errorf("%q. handleDeleteSecrets() invalid body", tt.name) + } + } + + }) + } +}