From 48de05f0787aa03ac88532a4fbb3cb1698a15c49 Mon Sep 17 00:00:00 2001 From: Vivek Singh Date: Sun, 5 Jan 2020 22:52:19 +0530 Subject: [PATCH] Update secret handler for PUT method This commit updates secrets handler for PUT method. It returns 405 "Method Not Allowed" for PUT method becuase secrets in docker swarm are immutable. Fixes: #65 Signed-off-by: Vivek Singh --- handlers/secrets.go | 76 ++++++++-------------------------------- handlers/secrets_test.go | 4 +-- 2 files changed, 17 insertions(+), 63 deletions(-) diff --git a/handlers/secrets.go b/handlers/secrets.go index c2abf9d9..f2339cde 100644 --- a/handlers/secrets.go +++ b/handlers/secrets.go @@ -4,12 +4,13 @@ import ( "context" "encoding/json" "fmt" - "github.com/docker/cli/opts" - "github.com/docker/docker/api/types/filters" "io/ioutil" "log" "net/http" + "github.com/docker/cli/opts" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" @@ -22,6 +23,7 @@ var ( ownerLabelValue = "openfaas" ) +//MakeSecretsHandler returns handler for managing secrets func MakeSecretsHandler(c client.SecretAPIClient) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Body != nil { @@ -31,9 +33,7 @@ func MakeSecretsHandler(c client.SecretAPIClient) http.HandlerFunc { body, readBodyErr := ioutil.ReadAll(r.Body) if readBodyErr != nil { log.Printf("couldn't read body of a request: %s", readBodyErr) - w.WriteHeader(http.StatusInternalServerError) - return } @@ -51,7 +51,8 @@ func MakeSecretsHandler(c client.SecretAPIClient) http.HandlerFunc { responseStatus, responseBody, responseErr = createNewSecret(c, body) break case http.MethodPut: - responseStatus, responseBody, responseErr = updateSecret(c, body) + responseStatus = http.StatusMethodNotAllowed + responseErr = fmt.Errorf("faas-swarm is unable to update secrets, delete and re-create or use a new name") break case http.MethodDelete: responseStatus, responseBody, responseErr = deleteSecret(c, body) @@ -60,20 +61,15 @@ func MakeSecretsHandler(c client.SecretAPIClient) http.HandlerFunc { if responseErr != nil { log.Println(responseErr) - w.WriteHeader(responseStatus) - return } if responseBody != nil { _, writeErr := w.Write(responseBody) - if writeErr != nil { log.Println("cannot write body of a response") - w.WriteHeader(http.StatusInternalServerError) - return } } @@ -99,28 +95,28 @@ func getSecretsWithLabel(c client.SecretAPIClient, labelName string, labelValue return filteredSecrets, nil } -func getSecretWithName(c client.SecretAPIClient, name string) (secret *swarm.Secret, err error, status int) { +func getSecretWithName(c client.SecretAPIClient, name string) (secret *swarm.Secret, status int, err error) { secrets, secretListErr := c.SecretList(context.Background(), types.SecretListOptions{}) if secretListErr != nil { - return nil, secretListErr, http.StatusInternalServerError + return nil, http.StatusInternalServerError, secretListErr } for _, secret := range secrets { if secret.Spec.Name == name { if secret.Spec.Labels[ownerLabel] == ownerLabelValue { - return &secret, nil, http.StatusOK + return &secret, http.StatusOK, nil } - return nil, fmt.Errorf( + return nil, http.StatusInternalServerError, fmt.Errorf( "found secret with name: %s, but it doesn't have label: %s == %s", name, ownerLabel, ownerLabelValue, - ), http.StatusInternalServerError + ) } } - return nil, fmt.Errorf("not found secret with name: %s", name), http.StatusNotFound + return nil, http.StatusNotFound, fmt.Errorf("unable to found secret with name: %s", name) } func getSecrets(c client.SecretAPIClient, _ []byte) (responseStatus int, responseBody []byte, err error) { @@ -140,7 +136,7 @@ func getSecrets(c client.SecretAPIClient, _ []byte) (responseStatus int, respons results = append(results, requests.Secret{Name: s.Spec.Name, Value: string(s.Spec.Data)}) } - resultsJson, marshalErr := json.Marshal(results) + resultsJSON, marshalErr := json.Marshal(results) if marshalErr != nil { return http.StatusInternalServerError, nil, @@ -148,7 +144,7 @@ func getSecrets(c client.SecretAPIClient, _ []byte) (responseStatus int, respons } - return http.StatusOK, resultsJson, nil + return http.StatusOK, resultsJSON, nil } func createNewSecret(c client.SecretAPIClient, body []byte) (responseStatus int, responseBody []byte, err error) { @@ -181,48 +177,6 @@ func createNewSecret(c client.SecretAPIClient, body []byte) (responseStatus int, return http.StatusCreated, nil, nil } -func updateSecret(c client.SecretAPIClient, body []byte) (responseStatus int, responseBody []byte, err error) { - var secret requests.Secret - - unmarshalErr := json.Unmarshal(body, &secret) - if unmarshalErr != nil { - return http.StatusBadRequest, nil, fmt.Errorf( - "error unmarshaling secret in secretPutHandler: %s", - unmarshalErr, - ) - } - - foundSecret, getSecretErr, status := getSecretWithName(c, secret.Name) - if getSecretErr != nil { - return status, nil, fmt.Errorf( - "cannot get secret with name: %s. Error: %s", - secret.Name, - getSecretErr.Error(), - ) - } - - updateSecretErr := c.SecretUpdate(context.Background(), foundSecret.ID, foundSecret.Version, swarm.SecretSpec{ - Annotations: swarm.Annotations{ - Name: secret.Name, - Labels: map[string]string{ - ownerLabel: ownerLabelValue, - }, - }, - Data: []byte(secret.Value), - }) - - if updateSecretErr != nil { - return http.StatusInternalServerError, nil, fmt.Errorf( - "couldn't update secret (name: %s, ID: %s) because of error: %s", - secret.Name, - foundSecret.ID, - updateSecretErr.Error(), - ) - } - - return http.StatusOK, nil, nil -} - func deleteSecret(c client.SecretAPIClient, body []byte) (responseStatus int, responseBody []byte, err error) { var secret requests.Secret @@ -234,7 +188,7 @@ func deleteSecret(c client.SecretAPIClient, body []byte) (responseStatus int, re ) } - foundSecret, getSecretErr, status := getSecretWithName(c, secret.Name) + foundSecret, status, getSecretErr := getSecretWithName(c, secret.Name) if getSecretErr != nil { return status, nil, fmt.Errorf( "cannot get secret with name: %s, which you want to remove. Error: %s", diff --git a/handlers/secrets_test.go b/handlers/secrets_test.go index eda9edd1..38d92207 100644 --- a/handlers/secrets_test.go +++ b/handlers/secrets_test.go @@ -167,8 +167,8 @@ func Test_SecretsHandler(t *testing.T) { secretsHandler(w, req) resp := w.Result() - if resp.StatusCode != http.StatusInternalServerError { - t.Errorf("expected status code '%d', got '%d'", http.StatusInternalServerError, resp.StatusCode) + if resp.StatusCode != http.StatusMethodNotAllowed { + t.Errorf("expected status code '%d', got '%d'", http.StatusMethodNotAllowed, resp.StatusCode) } })