github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/libpod/play.go (about)

     1  package libpod
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"os"
     8  
     9  	"github.com/containers/image/v5/types"
    10  	"github.com/containers/podman/v2/libpod"
    11  	"github.com/containers/podman/v2/pkg/api/handlers/utils"
    12  	"github.com/containers/podman/v2/pkg/auth"
    13  	"github.com/containers/podman/v2/pkg/domain/entities"
    14  	"github.com/containers/podman/v2/pkg/domain/infra/abi"
    15  	"github.com/gorilla/schema"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  func PlayKube(w http.ResponseWriter, r *http.Request) {
    20  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    21  	decoder := r.Context().Value("decoder").(*schema.Decoder)
    22  	query := struct {
    23  		Network   string `schema:"reference"`
    24  		TLSVerify bool   `schema:"tlsVerify"`
    25  		LogDriver string `schema:"logDriver"`
    26  		Start     bool   `schema:"start"`
    27  	}{
    28  		TLSVerify: true,
    29  		Start:     true,
    30  	}
    31  
    32  	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
    33  		utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
    34  			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
    35  		return
    36  	}
    37  
    38  	// Fetch the K8s YAML file from the body, and copy it to a temp file.
    39  	tmpfile, err := ioutil.TempFile("", "libpod-play-kube.yml")
    40  	if err != nil {
    41  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
    42  		return
    43  	}
    44  	defer os.Remove(tmpfile.Name())
    45  	if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
    46  		tmpfile.Close()
    47  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
    48  		return
    49  	}
    50  	if err := tmpfile.Close(); err != nil {
    51  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
    52  		return
    53  	}
    54  	authConf, authfile, key, err := auth.GetCredentials(r)
    55  	if err != nil {
    56  		utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
    57  		return
    58  	}
    59  	defer auth.RemoveAuthfile(authfile)
    60  	var username, password string
    61  	if authConf != nil {
    62  		username = authConf.Username
    63  		password = authConf.Password
    64  	}
    65  
    66  	containerEngine := abi.ContainerEngine{Libpod: runtime}
    67  	options := entities.PlayKubeOptions{
    68  		Authfile:  authfile,
    69  		Username:  username,
    70  		Password:  password,
    71  		Network:   query.Network,
    72  		Quiet:     true,
    73  		LogDriver: query.LogDriver,
    74  	}
    75  	if _, found := r.URL.Query()["tlsVerify"]; found {
    76  		options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
    77  	}
    78  	if _, found := r.URL.Query()["start"]; found {
    79  		options.Start = types.NewOptionalBool(query.Start)
    80  	}
    81  
    82  	report, err := containerEngine.PlayKube(r.Context(), tmpfile.Name(), options)
    83  	if err != nil {
    84  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error playing YAML file"))
    85  		return
    86  	}
    87  
    88  	utils.WriteResponse(w, http.StatusOK, report)
    89  }