From 832a69b0bee6ec289521fbd59ddd480372493ee3 Mon Sep 17 00:00:00 2001 From: Ashley Cui Date: Fri, 15 Jan 2021 01:27:23 -0500 Subject: Implement Secrets Implement podman secret create, inspect, ls, rm Implement podman run/create --secret Secrets are blobs of data that are sensitive. Currently, the only secret driver supported is filedriver, which means creating a secret stores it in base64 unencrypted in a file. After creating a secret, a user can use the --secret flag to expose the secret inside the container at /run/secrets/[secretname] This secret will not be commited to an image on a podman commit Signed-off-by: Ashley Cui --- pkg/api/handlers/compat/secrets.go | 121 +++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 pkg/api/handlers/compat/secrets.go (limited to 'pkg/api/handlers/compat/secrets.go') diff --git a/pkg/api/handlers/compat/secrets.go b/pkg/api/handlers/compat/secrets.go new file mode 100644 index 000000000..ea2dfc707 --- /dev/null +++ b/pkg/api/handlers/compat/secrets.go @@ -0,0 +1,121 @@ +package compat + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + + "github.com/containers/podman/v2/libpod" + "github.com/containers/podman/v2/pkg/api/handlers/utils" + "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/domain/infra/abi" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func ListSecrets(w http.ResponseWriter, r *http.Request) { + var ( + runtime = r.Context().Value("runtime").(*libpod.Runtime) + decoder = r.Context().Value("decoder").(*schema.Decoder) + ) + query := struct { + Filters map[string][]string `schema:"filters"` + }{} + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + if len(query.Filters) > 0 { + utils.Error(w, "filters not supported", http.StatusBadRequest, errors.New("bad parameter")) + } + ic := abi.ContainerEngine{Libpod: runtime} + reports, err := ic.SecretList(r.Context()) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, reports) +} + +func InspectSecret(w http.ResponseWriter, r *http.Request) { + var ( + runtime = r.Context().Value("runtime").(*libpod.Runtime) + ) + name := utils.GetName(r) + names := []string{name} + ic := abi.ContainerEngine{Libpod: runtime} + reports, errs, err := ic.SecretInspect(r.Context(), names) + if err != nil { + utils.InternalServerError(w, err) + return + } + if len(errs) > 0 { + utils.SecretNotFound(w, name, errs[0]) + return + } + utils.WriteResponse(w, http.StatusOK, reports[0]) + +} + +func RemoveSecret(w http.ResponseWriter, r *http.Request) { + var ( + runtime = r.Context().Value("runtime").(*libpod.Runtime) + ) + + opts := entities.SecretRmOptions{} + name := utils.GetName(r) + ic := abi.ContainerEngine{Libpod: runtime} + reports, err := ic.SecretRm(r.Context(), []string{name}, opts) + if err != nil { + utils.InternalServerError(w, err) + return + } + if reports[0].Err != nil { + utils.SecretNotFound(w, name, reports[0].Err) + return + } + utils.WriteResponse(w, http.StatusNoContent, nil) +} + +func CreateSecret(w http.ResponseWriter, r *http.Request) { + var ( + runtime = r.Context().Value("runtime").(*libpod.Runtime) + ) + opts := entities.SecretCreateOptions{} + createParams := struct { + *entities.SecretCreateRequest + Labels map[string]string `schema:"labels"` + }{} + + if err := json.NewDecoder(r.Body).Decode(&createParams); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) + return + } + if len(createParams.Labels) > 0 { + utils.Error(w, "labels not supported", http.StatusBadRequest, errors.New("bad parameter")) + } + + decoded, _ := base64.StdEncoding.DecodeString(createParams.Data) + reader := bytes.NewReader(decoded) + opts.Driver = createParams.Driver.Name + + ic := abi.ContainerEngine{Libpod: runtime} + report, err := ic.SecretCreate(r.Context(), createParams.Name, reader, opts) + if err != nil { + if errors.Cause(err).Error() == "secret name in use" { + utils.Error(w, "name conflicts with an existing object", http.StatusConflict, err) + return + } + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, report) +} + +func UpdateSecret(w http.ResponseWriter, r *http.Request) { + utils.Error(w, fmt.Sprintf("unsupported endpoint: %v", r.Method), http.StatusNotImplemented, errors.New("update is not supported")) +} -- cgit v1.2.3-54-g00ecf