summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJhon Honce <jhonce@redhat.com>2022-02-09 11:17:14 -0700
committerJhon Honce <jhonce@redhat.com>2022-02-09 14:22:42 -0700
commitc4676c571910d8b27ead751e35cbd877db61f8bd (patch)
tree5f921f64cb55969a87a48bedf445c8d58fe8cde8
parenteb0a0db318a988af9ed70f3cc3a68f3b2bf2aa93 (diff)
downloadpodman-c4676c571910d8b27ead751e35cbd877db61f8bd.tar.gz
podman-c4676c571910d8b27ead751e35cbd877db61f8bd.tar.bz2
podman-c4676c571910d8b27ead751e35cbd877db61f8bd.zip
Add version guard to libpod API endpoints
* Ensure meaningful behaviour when called with /v3.x.x semantics * Change return code to 409 from 500 when client attempts to use an existing network name * Update API bats test runner to support /v4.0.0 endpoints by default Signed-off-by: Jhon Honce <jhonce@redhat.com>
-rw-r--r--pkg/api/handlers/libpod/networks.go66
-rw-r--r--pkg/bindings/test/networks_test.go4
-rw-r--r--test/apiv2/35-networks.at5
-rwxr-xr-xtest/apiv2/test-apiv210
4 files changed, 60 insertions, 25 deletions
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 71d46ce70..16f499d4c 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -17,22 +17,37 @@ import (
)
func CreateNetwork(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
network := types.Network{}
if err := json.NewDecoder(r.Body).Decode(&network); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "decode body"))
+ utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "failed to decode request JSON payload"))
return
}
ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.NetworkCreate(r.Context(), network)
if err != nil {
- utils.InternalServerError(w, err)
+ if errors.Is(err, types.ErrNetworkExists) {
+ utils.Error(w, http.StatusConflict, err)
+ } else {
+ utils.InternalServerError(w, err)
+ }
return
}
utils.WriteResponse(w, http.StatusOK, report)
}
+
func ListNetworks(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
filterMap, err := util.PrepareFilters(r)
if err != nil {
@@ -54,6 +69,11 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
}
func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -87,21 +107,18 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, reports)
}
+// InspectNetwork reports on given network's details
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- query := struct {
- }{
- // override any golang type defaults
- }
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusInternalServerError,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
return
}
+
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ ic := abi.ContainerEngine{Libpod: runtime}
+
name := utils.GetName(r)
options := entities.InspectOptions{}
- ic := abi.ContainerEngine{Libpod: runtime}
reports, errs, err := ic.NetworkInspect(r.Context(), []string{name}, options)
// If the network cannot be found, we return a 404.
if len(errs) > 0 {
@@ -117,14 +134,19 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
// Connect adds a container to a network
func Connect(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
var netConnect entities.NetworkConnectOptions
if err := json.NewDecoder(r.Body).Decode(&netConnect); err != nil {
- utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
+ utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "failed to decode request JSON payload"))
return
}
name := utils.GetName(r)
+
err := runtime.ConnectContainerToNetwork(netConnect.Container, name, netConnect.PerNetworkOptions)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
@@ -143,10 +165,15 @@ func Connect(w http.ResponseWriter, r *http.Request) {
// ExistsNetwork check if a network exists
func ExistsNetwork(w http.ResponseWriter, r *http.Request) {
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- name := utils.GetName(r)
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
ic := abi.ContainerEngine{Libpod: runtime}
+
+ name := utils.GetName(r)
report, err := ic.NetworkExists(r.Context(), name)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
@@ -161,7 +188,13 @@ func ExistsNetwork(w http.ResponseWriter, r *http.Request) {
// Prune removes unused networks
func Prune(w http.ResponseWriter, r *http.Request) {
+ if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
+ utils.BadRequest(w, "version", v.String(), err)
+ return
+ }
+
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+ ic := abi.ContainerEngine{Libpod: runtime}
filterMap, err := util.PrepareFilters(r)
if err != nil {
@@ -172,7 +205,6 @@ func Prune(w http.ResponseWriter, r *http.Request) {
pruneOptions := entities.NetworkPruneOptions{
Filters: *filterMap,
}
- ic := abi.ContainerEngine{Libpod: runtime}
pruneReports, err := ic.NetworkPrune(r.Context(), pruneOptions)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
diff --git a/pkg/bindings/test/networks_test.go b/pkg/bindings/test/networks_test.go
index ee2d6f472..137db71a3 100644
--- a/pkg/bindings/test/networks_test.go
+++ b/pkg/bindings/test/networks_test.go
@@ -80,7 +80,7 @@ var _ = Describe("Podman networks", func() {
// Valid filter params => network should be pruned now.
filters = map[string][]string{
- "until": {"5000000000"}, //June 11, 2128
+ "until": {"5000000000"}, // June 11, 2128
}
pruneResponse, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filters))
Expect(err).To(BeNil())
@@ -105,7 +105,7 @@ var _ = Describe("Podman networks", func() {
_, err = network.Create(connText, &net)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
- Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
+ Expect(code).To(BeNumerically("==", http.StatusConflict))
})
It("inspect network", func() {
diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at
index 0e2389bd5..3502b89e0 100644
--- a/test/apiv2/35-networks.at
+++ b/test/apiv2/35-networks.at
@@ -8,7 +8,10 @@ t GET networks/non-existing-network 404 \
t POST libpod/networks/create name='"network1"' 200 \
.name=network1 \
- .created~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
+ .created~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.*
+
+t POST /v3.4.0/libpod/networks/create name='"bad_version"' 400 \
+ .cause='given version is not supported'
# --data '{"name":"network2","subnets":[{"subnet":"10.10.254.0/24"}],"Labels":{"abc":"val"}}'
t POST libpod/networks/create name='"network2"' \
diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2
index 56280f04e..bd728e130 100755
--- a/test/apiv2/test-apiv2
+++ b/test/apiv2/test-apiv2
@@ -256,11 +256,11 @@ function t() {
# If given path begins with /, use it as-is; otherwise prepend /version/
local url=http://$HOST:$PORT
- if expr "$path" : "/" >/dev/null; then
- url="$url$path"
- else
- url="$url/v1.40/$path"
- fi
+ case "$path" in
+ /*) url="$url$path" ;;
+ libpod/*) url="$url/v4.0.0/$path" ;;
+ *) url="$url/v1.41/$path" ;;
+ esac
# Log every action we do
echo "-------------------------------------------------------------" >>$LOG