diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/auth.go | 59 | ||||
-rw-r--r-- | pkg/api/handlers/compat/volumes.go | 34 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/networks.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/swagger.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_auth.go | 24 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 9 | ||||
-rw-r--r-- | pkg/bindings/images/build.go | 18 | ||||
-rw-r--r-- | pkg/bindings/network/network.go | 3 | ||||
-rw-r--r-- | pkg/domain/entities/system.go | 11 |
9 files changed, 137 insertions, 25 deletions
diff --git a/pkg/api/handlers/compat/auth.go b/pkg/api/handlers/compat/auth.go new file mode 100644 index 000000000..2c152fbc2 --- /dev/null +++ b/pkg/api/handlers/compat/auth.go @@ -0,0 +1,59 @@ +package compat + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + + DockerClient "github.com/containers/image/v5/docker" + "github.com/containers/image/v5/types" + "github.com/containers/podman/v3/pkg/api/handlers/utils" + "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/pkg/registries" + docker "github.com/docker/docker/api/types" + "github.com/pkg/errors" +) + +func stripAddressOfScheme(address string) string { + for _, s := range []string{"https", "http"} { + address = strings.TrimPrefix(address, s+"://") + } + return address +} + +func Auth(w http.ResponseWriter, r *http.Request) { + var authConfig docker.AuthConfig + err := json.NewDecoder(r.Body).Decode(&authConfig) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse request")) + return + } + + skipTLS := types.NewOptionalBool(false) + if strings.HasPrefix(authConfig.ServerAddress, "https://localhost/") || strings.HasPrefix(authConfig.ServerAddress, "https://localhost:") || strings.HasPrefix(authConfig.ServerAddress, "localhost:") { + // support for local testing + skipTLS = types.NewOptionalBool(true) + } + + fmt.Println("Authenticating with existing credentials...") + sysCtx := types.SystemContext{ + AuthFilePath: "", + DockerCertPath: "", + DockerInsecureSkipTLSVerify: skipTLS, + SystemRegistriesConfPath: registries.SystemRegistriesConfPath(), + } + registry := stripAddressOfScheme(authConfig.ServerAddress) + if err := DockerClient.CheckAuth(context.Background(), &sysCtx, authConfig.Username, authConfig.Password, registry); err == nil { + utils.WriteResponse(w, http.StatusOK, entities.AuthReport{ + IdentityToken: "", + Status: "Login Succeeded", + }) + } else { + utils.WriteResponse(w, http.StatusBadRequest, entities.AuthReport{ + IdentityToken: "", + Status: "login attempt to " + authConfig.ServerAddress + " failed with status: " + err.Error(), + }) + } +} diff --git a/pkg/api/handlers/compat/volumes.go b/pkg/api/handlers/compat/volumes.go index 28fb67102..d2febc615 100644 --- a/pkg/api/handlers/compat/volumes.go +++ b/pkg/api/handlers/compat/volumes.go @@ -5,6 +5,7 @@ import ( "encoding/json" "net/http" "net/url" + "strings" "time" "github.com/containers/podman/v3/libpod" @@ -31,7 +32,7 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) { } if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } @@ -40,7 +41,7 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) { // happily parse them for us. for filter := range query.Filters { if filter == "opts" { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError, errors.Errorf("unsupported libpod filters passed to docker endpoint")) return } @@ -90,7 +91,7 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) { /* No query string data*/ query := struct{}{} if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } @@ -218,7 +219,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) { } if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } @@ -263,25 +264,24 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) { func PruneVolumes(w http.ResponseWriter, r *http.Request) { var ( runtime = r.Context().Value("runtime").(*libpod.Runtime) - decoder = r.Context().Value("decoder").(*schema.Decoder) ) - // For some reason the prune filters are query parameters even though this - // is a POST endpoint - query := struct { - Filters map[string][]string `schema:"filters"` - }{ - // override any golang type defaults - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + filtersList, err := filtersFromRequest(r) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) return } + filterMap := map[string][]string{} + for _, filter := range filtersList { + split := strings.SplitN(filter, "=", 2) + if len(split) > 1 { + filterMap[split[0]] = append(filterMap[split[0]], split[1]) + } + } - f := (url.Values)(query.Filters) + f := (url.Values)(filterMap) filterFuncs, err := filters.GenerateVolumeFilters(f) if err != nil { - utils.Error(w, "Something when wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse filters for %s", f.Encode())) + utils.Error(w, "Something when wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse filters for %s", f.Encode())) return } diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go index 5982f50a7..19c9ed658 100644 --- a/pkg/api/handlers/libpod/networks.go +++ b/pkg/api/handlers/libpod/networks.go @@ -128,7 +128,7 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } - utils.WriteResponse(w, http.StatusOK, reports) + utils.WriteResponse(w, http.StatusOK, reports[0]) } // Connect adds a container to a network diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go index 1bececa1a..2631f19ac 100644 --- a/pkg/api/handlers/libpod/swagger.go +++ b/pkg/api/handlers/libpod/swagger.go @@ -102,7 +102,7 @@ type swagNetworkRmReport struct { // swagger:response NetworkInspectReport type swagNetworkInspectReport struct { // in:body - Body []entities.NetworkInspectReport + Body entities.NetworkInspectReport } // Network list diff --git a/pkg/api/server/register_auth.go b/pkg/api/server/register_auth.go index 1e5474462..56e115e30 100644 --- a/pkg/api/server/register_auth.go +++ b/pkg/api/server/register_auth.go @@ -1,13 +1,33 @@ package server import ( + "net/http" + "github.com/containers/podman/v3/pkg/api/handlers/compat" "github.com/gorilla/mux" ) func (s *APIServer) registerAuthHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/auth"), s.APIHandler(compat.UnsupportedHandler)) + // swagger:operation POST /auth compat auth + // --- + // summary: Check auth configuration + // tags: + // - system (compat) + // produces: + // - application/json + // parameters: + // - in: body + // name: authConfig + // description: Authentication to check + // schema: + // $ref: "#/definitions/AuthConfig" + // responses: + // 200: + // $ref: "#/responses/SystemAuthResponse" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/auth"), s.APIHandler(compat.Auth)).Methods(http.MethodPost) // Added non version path to URI to support docker non versioned paths - r.Handle("/auth", s.APIHandler(compat.UnsupportedHandler)) + r.Handle("/auth", s.APIHandler(compat.Auth)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 92efb8ef3..12fd083bb 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -226,3 +226,12 @@ type swagSystemPruneReport struct { entities.SystemPruneReport } } + +// Auth response +// swagger:response SystemAuthResponse +type swagSystemAuthResponse struct { + // in:body + Body struct { + entities.AuthReport + } +} diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 1cbd28c37..9d77883f9 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -20,6 +20,7 @@ import ( "github.com/containers/podman/v3/pkg/bindings" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/storage/pkg/fileutils" + "github.com/containers/storage/pkg/ioutils" "github.com/docker/go-units" "github.com/hashicorp/go-multierror" jsoniter "github.com/json-iterator/go" @@ -252,7 +253,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO logrus.Errorf("cannot tar container entries %v error: %v", entries, err) return nil, err } - defer tarfile.Close() + defer func() { + if err := tarfile.Close(); err != nil { + logrus.Errorf("%v\n", err) + } + }() containerFile, err := filepath.Abs(entries[0]) if err != nil { @@ -340,7 +345,7 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { gw := gzip.NewWriter(pw) tw := tar.NewWriter(gw) - var merr error + var merr *multierror.Error go func() { defer pw.Close() defer gw.Close() @@ -421,7 +426,14 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { merr = multierror.Append(merr, err) } }() - return pr, merr + rc := ioutils.NewReadCloserWrapper(pr, func() error { + if merr != nil { + merr = multierror.Append(merr, pr.Close()) + return merr.ErrorOrNil() + } + return pr.Close() + }) + return rc, nil } func parseDockerignore(root string) ([]string, error) { diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index 46a3719fe..6f3aa8594 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -40,6 +40,7 @@ func Create(ctx context.Context, options *CreateOptions) (*entities.NetworkCreat // Inspect returns low level information about a CNI network configuration func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) ([]entities.NetworkInspectReport, error) { var reports []entities.NetworkInspectReport + reports = append(reports, entities.NetworkInspectReport{}) if options == nil { options = new(InspectOptions) } @@ -52,7 +53,7 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) ([]e if err != nil { return nil, err } - return reports, response.Process(&reports) + return reports, response.Process(&reports[0]) } // Remove deletes a defined CNI network configuration by name. The optional force boolean diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go index a1cfb4481..4b8383613 100644 --- a/pkg/domain/entities/system.go +++ b/pkg/domain/entities/system.go @@ -107,3 +107,14 @@ type ComponentVersion struct { type ListRegistriesReport struct { Registries []string } + +// swagger:model AuthConfig +type AuthConfig struct { + types.AuthConfig +} + +// AuthReport describes the response for authentication check +type AuthReport struct { + IdentityToken string + Status string +} |