From f269be3a314a0903bb74a20de0e93b4f274531e6 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Tue, 5 May 2020 11:35:32 +0200 Subject: add {generate,play} kube Add the `podman generate kube` and `podman play kube` command. The code has largely been copied from Podman v1 but restructured to not leak the K8s core API into the (remote) client. Both commands are added in the same commit to allow for enabling the tests at the same time. Move some exports from `cmd/podman/common` to the appropriate places in the backend to avoid circular dependencies. Move definitions of label annotations to `libpod/define` and set the security-opt labels in the frontend to make kube tests pass. Implement rest endpoints, bindings and the tunnel interface. Signed-off-by: Valentin Rothberg --- pkg/api/handlers/libpod/generate.go | 38 ++++++++++++++++++++++ pkg/api/handlers/libpod/play.go | 64 +++++++++++++++++++++++++++++++++++++ pkg/api/handlers/swagger/swagger.go | 7 ++++ 3 files changed, 109 insertions(+) create mode 100644 pkg/api/handlers/libpod/generate.go create mode 100644 pkg/api/handlers/libpod/play.go (limited to 'pkg/api/handlers') diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go new file mode 100644 index 000000000..23320d346 --- /dev/null +++ b/pkg/api/handlers/libpod/generate.go @@ -0,0 +1,38 @@ +package libpod + +import ( + "net/http" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/infra/abi" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func GenerateKube(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Service bool `schema:"service"` + }{ + // Defaults would go here. + } + + 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 + } + + containerEngine := abi.ContainerEngine{Libpod: runtime} + options := entities.GenerateKubeOptions{Service: query.Service} + report, err := containerEngine.GenerateKube(r.Context(), utils.GetName(r), options) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error generating YAML")) + return + } + + utils.WriteResponse(w, http.StatusOK, report.Reader) +} diff --git a/pkg/api/handlers/libpod/play.go b/pkg/api/handlers/libpod/play.go new file mode 100644 index 000000000..26e02bf4f --- /dev/null +++ b/pkg/api/handlers/libpod/play.go @@ -0,0 +1,64 @@ +package libpod + +import ( + "io" + "io/ioutil" + "net/http" + "os" + + "github.com/containers/image/v5/types" + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/infra/abi" + "github.com/gorilla/schema" + "github.com/pkg/errors" +) + +func PlayKube(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Network string `schema:"reference"` + TLSVerify bool `schema:"tlsVerify"` + }{ + TLSVerify: true, + } + + 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 + } + + // Fetch the K8s YAML file from the body, and copy it to a temp file. + tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml") + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile")) + return + } + defer os.Remove(tmpfile.Name()) + if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF { + tmpfile.Close() + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file")) + return + } + if err := tmpfile.Close(); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file")) + return + } + + containerEngine := abi.ContainerEngine{Libpod: runtime} + options := entities.PlayKubeOptions{Network: query.Network, Quiet: true} + if _, found := r.URL.Query()["tlsVerify"]; found { + options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) + } + + report, err := containerEngine.PlayKube(r.Context(), tmpfile.Name(), options) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error playing YAML file")) + return + } + + utils.WriteResponse(w, http.StatusOK, report) +} diff --git a/pkg/api/handlers/swagger/swagger.go b/pkg/api/handlers/swagger/swagger.go index 0aceaf5f6..5d125417b 100644 --- a/pkg/api/handlers/swagger/swagger.go +++ b/pkg/api/handlers/swagger/swagger.go @@ -56,6 +56,13 @@ type swagLibpodImagesRemoveResponse struct { Body handlers.LibpodImagesRemoveReport } +// PlayKube response +// swagger:response DocsLibpodPlayKubeResponse +type swagLibpodPlayKubeResponse struct { + // in:body + Body entities.PlayKubeReport +} + // Delete response // swagger:response DocsImageDeleteResponse type swagImageDeleteResponse struct { -- cgit v1.2.3-54-g00ecf