mirror of
https://github.com/containers/podman.git
synced 2025-11-01 22:32:50 +08:00
Add X-Registry-Config support
* Refactor auth pkg to support X-Registry-Config * Refactor build endpoint to support X-Registry-Config. Supports: * --creds * --authfile * Added X-Reference-Id Header to http.Request to support log event correlation * Log headers from http.Request Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
@ -93,7 +93,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
//FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
|
||||
// FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
|
||||
ipr := types.ImagesPruneReport{
|
||||
ImagesDeleted: idr,
|
||||
SpaceReclaimed: 1, // TODO we cannot supply this right now
|
||||
@ -113,7 +113,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
Changes string `schema:"changes"`
|
||||
Comment string `schema:"comment"`
|
||||
Container string `schema:"container"`
|
||||
//fromSrc string # fromSrc is currently unused
|
||||
// fromSrc string # fromSrc is currently unused
|
||||
Pause bool `schema:"pause"`
|
||||
Repo string `schema:"repo"`
|
||||
Tag string `schema:"tag"`
|
||||
@ -224,7 +224,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
|
||||
Status string `json:"status"`
|
||||
Progress string `json:"progress"`
|
||||
ProgressDetail map[string]string `json:"progressDetail"`
|
||||
Id string `json:"id"` //nolint
|
||||
Id string `json:"id"` // nolint
|
||||
}{
|
||||
Status: iid,
|
||||
ProgressDetail: map[string]string{},
|
||||
@ -257,9 +257,9 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
|
||||
fromImage = fmt.Sprintf("%s:%s", fromImage, query.Tag)
|
||||
}
|
||||
|
||||
authConf, authfile, err := auth.GetCredentials(r)
|
||||
authConf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
|
||||
utils.Error(w, "Failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", key, r.URL.String()))
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
@ -299,7 +299,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
|
||||
Error string `json:"error"`
|
||||
Progress string `json:"progress"`
|
||||
ProgressDetail map[string]string `json:"progressDetail"`
|
||||
Id string `json:"id"` //nolint
|
||||
Id string `json:"id"` // nolint
|
||||
}{
|
||||
Status: fmt.Sprintf("pulling image (%s) from %s", img.Tag, strings.Join(img.Names(), ", ")),
|
||||
ProgressDetail: map[string]string{},
|
||||
|
||||
@ -2,7 +2,6 @@ package compat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -11,13 +10,13 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/imagebuildah"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/podman/v2/libpod"
|
||||
"github.com/containers/podman/v2/pkg/api/handlers"
|
||||
"github.com/containers/podman/v2/pkg/api/handlers/utils"
|
||||
"github.com/containers/podman/v2/pkg/auth"
|
||||
"github.com/containers/podman/v2/pkg/channel"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/gorilla/schema"
|
||||
@ -26,15 +25,6 @@ import (
|
||||
)
|
||||
|
||||
func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
authConfigs := map[string]handlers.AuthConfig{}
|
||||
if hdr, found := r.Header["X-Registry-Config"]; found && len(hdr) > 0 {
|
||||
authConfigsJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(hdr[0]))
|
||||
if json.NewDecoder(authConfigsJSON).Decode(&authConfigs) != nil {
|
||||
utils.BadRequest(w, "X-Registry-Config", hdr[0], json.NewDecoder(authConfigsJSON).Decode(&authConfigs))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if hdr, found := r.Header["Content-Type"]; found && len(hdr) > 0 {
|
||||
contentType := hdr[0]
|
||||
switch contentType {
|
||||
@ -151,6 +141,14 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
creds, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
// Credential value(s) not returned as their value is not human readable
|
||||
utils.BadRequest(w, key.String(), "n/a", err)
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
// Channels all mux'ed in select{} below to follow API build protocol
|
||||
stdout := channel.NewWriter(make(chan []byte, 1))
|
||||
defer stdout.Close()
|
||||
@ -179,6 +177,10 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
Err: auxout,
|
||||
ReportWriter: reporter,
|
||||
OutputFormat: buildah.Dockerv2ImageManifest,
|
||||
SystemContext: &types.SystemContext{
|
||||
AuthFilePath: authfile,
|
||||
DockerAuthConfig: creds,
|
||||
},
|
||||
CommonBuildOpts: &buildah.CommonBuildOptions{
|
||||
CPUPeriod: query.CpuPeriod,
|
||||
CPUQuota: query.CpuQuota,
|
||||
|
||||
@ -49,9 +49,9 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authConf, authfile, err := auth.GetCredentials(r)
|
||||
authConf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", key, r.URL.String()))
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
@ -438,9 +438,9 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authConf, authfile, err := auth.GetCredentials(r)
|
||||
authConf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
|
||||
utils.Error(w, "Failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", key, r.URL.String()))
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
@ -74,9 +74,9 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
authConf, authfile, err := auth.GetCredentials(r)
|
||||
authConf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
|
||||
utils.Error(w, "Failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", key, r.URL.String()))
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
@ -48,9 +48,9 @@ func PlayKube(w http.ResponseWriter, r *http.Request) {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error closing temporary file"))
|
||||
return
|
||||
}
|
||||
authConf, authfile, err := auth.GetCredentials(r)
|
||||
authConf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", auth.XRegistryAuthHeader, r.URL.String()))
|
||||
utils.Error(w, "Failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse %q header for %s", key, r.URL.String()))
|
||||
return
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
@ -7,7 +7,9 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/containers/podman/v2/pkg/api/handlers/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/containers/podman/v2/pkg/auth"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// APIHandler is a wrapper to enhance HandlerFunc's and remove redundant code
|
||||
@ -19,7 +21,7 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
|
||||
if err != nil {
|
||||
buf := make([]byte, 1<<20)
|
||||
n := runtime.Stack(buf, true)
|
||||
log.Warnf("Recovering from API handler panic: %v, %s", err, buf[:n])
|
||||
logrus.Warnf("Recovering from API handler panic: %v, %s", err, buf[:n])
|
||||
// Try to inform client things went south... won't work if handler already started writing response body
|
||||
utils.InternalServerError(w, fmt.Errorf("%v", err))
|
||||
}
|
||||
@ -27,10 +29,23 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
|
||||
|
||||
// Wrapper to hide some boiler plate
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debugf("APIHandler -- Method: %s URL: %s", r.Method, r.URL.String())
|
||||
rid := uuid.New().String()
|
||||
if logrus.IsLevelEnabled(logrus.DebugLevel) {
|
||||
logrus.Debugf("APIHandler(%s) -- Method: %s URL: %s", rid, r.Method, r.URL.String())
|
||||
for k, v := range r.Header {
|
||||
switch auth.HeaderAuthName(k) {
|
||||
case auth.XRegistryConfigHeader, auth.XRegistryAuthHeader:
|
||||
logrus.Debugf("APIHandler(%s) -- Header: %s: <hidden>", rid, k)
|
||||
default:
|
||||
logrus.Debugf("APIHandler(%s) -- Header: %s: %v", rid, k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set in case handler wishes to correlate logging events
|
||||
r.Header.Set("X-Reference-Id", rid)
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
log.Infof("Failed Request: unable to parse form: %q", err)
|
||||
logrus.Infof("Failed Request: unable to parse form: %q (%s)", err, rid)
|
||||
}
|
||||
|
||||
// TODO: Use r.ConnContext when ported to go 1.13
|
||||
|
||||
Reference in New Issue
Block a user