APIv2 compatibility network connect|disconnect

Add endpoints for the compat layer for network connect and disconnect. As of now, these two endpoints do nothing to change the network state of a container.  They do some basic data verification and return the proper 200 response.  This at least allows for scripts to work on the compatibility layer instead of getting 404s.

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude 2020-10-20 12:10:58 -05:00
parent 2cd2359a6d
commit 6841936525
5 changed files with 158 additions and 19 deletions

View file

@ -73,8 +73,8 @@ func generateEventUntilOption(timeUntil time.Time) func(e *Event) bool {
}
func parseFilter(filter string) (string, string, error) {
filterSplit := strings.Split(filter, "=")
if len(filterSplit) != 2 {
filterSplit := strings.SplitN(filter, "=", 2)
if len(filterSplit) == 1 {
return "", "", errors.Errorf("%s is an invalid filter", filter)
}
return filterSplit[0], filterSplit[1], nil

View file

@ -410,25 +410,14 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
return nil, err
}
networkSettingsDefault := types.DefaultNetworkSettings{
EndpointID: "",
Gateway: "",
GlobalIPv6Address: "",
GlobalIPv6PrefixLen: 0,
IPAddress: "",
IPPrefixLen: 0,
IPv6Gateway: "",
MacAddress: l.Config().StaticMAC.String(),
n, err := json.Marshal(inspect.NetworkSettings)
if err != nil {
return nil, err
}
networkSettingsBase := types.NetworkSettingsBase{
Ports: ports,
}
networkSettings := types.NetworkSettings{
NetworkSettingsBase: networkSettingsBase,
DefaultNetworkSettings: networkSettingsDefault,
Networks: nil,
networkSettings := types.NetworkSettings{}
if err := json.Unmarshal(n, &networkSettings); err != nil {
return nil, err
}
c := types.ContainerJSON{

View file

@ -20,6 +20,7 @@ import (
dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
@ -312,3 +313,81 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusNoContent, "")
}
// Connect adds a container to a network
// TODO: For now this func is a no-op that checks the container name, network name, and
// responds with a 200. This allows the call to remain intact. We need to decide how
// we make this work with CNI networking and setup/teardown.
func Connect(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
var netConnect types.NetworkConnect
if err := json.NewDecoder(r.Body).Decode(&netConnect); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
config, err := runtime.GetConfig()
if err != nil {
utils.InternalServerError(w, err)
return
}
name := utils.GetName(r)
exists, err := network.Exists(config, name)
if err != nil {
utils.InternalServerError(w, err)
return
}
if !exists {
utils.Error(w, "network not found", http.StatusNotFound, define.ErrNoSuchNetwork)
return
}
if _, err = runtime.LookupContainer(netConnect.Container); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, netConnect.Container, err)
return
}
utils.Error(w, "unable to lookup container", http.StatusInternalServerError, err)
return
}
logrus.Warnf("network connect endpoint is not fully implemented - tried to connect container %s to network %s", netConnect.Container, name)
utils.WriteResponse(w, http.StatusOK, "OK")
}
// Disconnect removes a container from a network
// TODO: For now this func is a no-op that checks the container name, network name, and
// responds with a 200. This allows the call to remain intact. We need to decide how
// we make this work with CNI networking and setup/teardown.
func Disconnect(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
var netDisconnect types.NetworkDisconnect
if err := json.NewDecoder(r.Body).Decode(&netDisconnect); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
return
}
config, err := runtime.GetConfig()
if err != nil {
utils.InternalServerError(w, err)
return
}
name := utils.GetName(r)
exists, err := network.Exists(config, name)
if err != nil {
utils.InternalServerError(w, err)
return
}
if !exists {
utils.Error(w, "network not found", http.StatusNotFound, define.ErrNoSuchNetwork)
return
}
if _, err = runtime.LookupContainer(netDisconnect.Container); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, netDisconnect.Container, err)
return
}
utils.Error(w, "unable to lookup container", http.StatusInternalServerError, err)
return
}
logrus.Warnf("network disconnect endpoint is not fully implemented - tried to connect container %s to network %s", netDisconnect.Container, name)
utils.WriteResponse(w, http.StatusOK, "OK")
}

View file

@ -63,3 +63,17 @@ type swagCompatNetworkCreateResponse struct {
// in:body
Body struct{ types.NetworkCreate }
}
// Network disconnect
// swagger:model NetworkConnectRequest
type swagCompatNetworkConnectRequest struct {
// in:body
Body struct{ types.NetworkConnect }
}
// Network disconnect
// swagger:model NetworkDisconnectRequest
type swagCompatNetworkDisconnectRequest struct {
// in:body
Body struct{ types.NetworkDisconnect }
}

View file

@ -98,6 +98,63 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/networks/create"), s.APIHandler(compat.CreateNetwork)).Methods(http.MethodPost)
r.HandleFunc("/networks/create", s.APIHandler(compat.CreateNetwork)).Methods(http.MethodPost)
// swagger:operation POST /networks/{name}/connect compat compatConnectNetwork
// ---
// tags:
// - networks (compat)
// summary: Connect container to network
// description: Connect a container to a network. This endpoint is current a no-op
// produces:
// - application/json
// parameters:
// - in: path
// name: name
// type: string
// required: true
// description: the name of the network
// - in: body
// name: create
// description: attributes for connecting a container to a network
// schema:
// $ref: "#/definitions/NetworkConnectRequest"
// responses:
// 200:
// description: OK
// 400:
// $ref: "#/responses/BadParamError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/networks/{name}/connect"), s.APIHandler(compat.Connect)).Methods(http.MethodPost)
r.HandleFunc("/networks/{name}/connect", s.APIHandler(compat.Connect)).Methods(http.MethodPost)
// swagger:operation POST /networks/{name}/disconnect compat compatDisconnectNetwork
// ---
// tags:
// - networks (compat)
// summary: Disconnect container from network
// description: Disconnect a container from a network. This endpoint is current a no-op
// produces:
// - application/json
// parameters:
// - in: path
// name: name
// type: string
// required: true
// description: the name of the network
// - in: body
// name: create
// description: attributes for disconnecting a container from a network
// schema:
// $ref: "#/definitions/NetworkDisconnectRequest"
// responses:
// 200:
// description: OK
// 400:
// $ref: "#/responses/BadParamError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/networks/{name}/disconnect"), s.APIHandler(compat.Disconnect)).Methods(http.MethodPost)
r.HandleFunc("/networks/{name}/disconnect", s.APIHandler(compat.Disconnect)).Methods(http.MethodPost)
// swagger:operation DELETE /libpod/networks/{name} libpod libpodRemoveNetwork
// ---
// tags: