daemon: Return all validation errors for NetworkingConfig and EndpointSettings
Thus far, validation code would stop as soon as a bad value was found. Now, we try to validate as much as we can, to return all errors to the API client. Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This commit is contained in:
parent
ff503882f7
commit
4bd0553274
3 changed files with 21 additions and 9 deletions
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/daemon/network"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/multierror"
|
||||
"github.com/docker/docker/libnetwork"
|
||||
"github.com/docker/docker/libnetwork/netlabel"
|
||||
"github.com/docker/docker/libnetwork/options"
|
||||
|
@ -575,30 +576,32 @@ func validateEndpointSettings(nw *libnetwork.Network, nwName string, epConfig *n
|
|||
ipamConfig = epConfig.IPAMConfig
|
||||
}
|
||||
|
||||
var errs []error
|
||||
|
||||
if !containertypes.NetworkMode(nwName).IsUserDefined() {
|
||||
hasStaticAddresses := ipamConfig.IPv4Address != "" || ipamConfig.IPv6Address != ""
|
||||
// On Linux, user specified IP address is accepted only by networks with user specified subnets.
|
||||
if hasStaticAddresses && !enableIPOnPredefinedNetwork() {
|
||||
return runconfig.ErrUnsupportedNetworkAndIP
|
||||
errs = append(errs, runconfig.ErrUnsupportedNetworkAndIP)
|
||||
}
|
||||
if len(epConfig.Aliases) > 0 && !serviceDiscoveryOnDefaultNetwork() {
|
||||
return runconfig.ErrUnsupportedNetworkAndAlias
|
||||
errs = append(errs, runconfig.ErrUnsupportedNetworkAndAlias)
|
||||
}
|
||||
}
|
||||
|
||||
if ipamConfig.IPv4Address != "" {
|
||||
if addr := net.ParseIP(ipamConfig.IPv4Address); addr == nil || addr.To4() == nil || addr.IsUnspecified() {
|
||||
return fmt.Errorf("invalid IPv4 address: %s", ipamConfig.IPv4Address)
|
||||
errs = append(errs, fmt.Errorf("invalid IPv4 address: %s", ipamConfig.IPv4Address))
|
||||
}
|
||||
}
|
||||
if ipamConfig.IPv6Address != "" {
|
||||
if addr := net.ParseIP(ipamConfig.IPv6Address); addr == nil || addr.To4() != nil || addr.IsUnspecified() {
|
||||
return fmt.Errorf("invalid IPv6 address: %s", ipamConfig.IPv6Address)
|
||||
errs = append(errs, fmt.Errorf("invalid IPv6 address: %s", ipamConfig.IPv6Address))
|
||||
}
|
||||
}
|
||||
|
||||
if nw == nil {
|
||||
return nil
|
||||
return multierror.Join(errs...)
|
||||
}
|
||||
|
||||
_, _, nwIPv4Configs, nwIPv6Configs := nw.IpamConfig()
|
||||
|
@ -624,12 +627,12 @@ func validateEndpointSettings(nw *libnetwork.Network, nwName string, epConfig *n
|
|||
}
|
||||
}
|
||||
if !foundSubnet {
|
||||
return runconfig.ErrUnsupportedNetworkNoSubnetAndIP
|
||||
errs = append(errs, runconfig.ErrUnsupportedNetworkNoSubnetAndIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return multierror.Join(errs...)
|
||||
}
|
||||
|
||||
// cleanOperationalData resets the operational data from the passed endpoint settings
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/docker/docker/daemon/images"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/internal/multierror"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/runconfig"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
@ -326,18 +327,24 @@ func (daemon *Daemon) validateNetworkingConfig(nwConfig *networktypes.Networking
|
|||
return nil
|
||||
}
|
||||
|
||||
var errs []error
|
||||
for k, v := range nwConfig.EndpointsConfig {
|
||||
if v == nil {
|
||||
return fmt.Errorf("no EndpointSettings for %s", k)
|
||||
errs = append(errs, fmt.Errorf("invalid config for network %s: EndpointsConfig is nil", k))
|
||||
continue
|
||||
}
|
||||
|
||||
// The referenced network k might not exist when the container is created, so just ignore the error in that case.
|
||||
nw, _ := daemon.FindNetwork(k)
|
||||
if err := validateEndpointSettings(nw, k, v); err != nil {
|
||||
return err
|
||||
errs = append(errs, fmt.Errorf("invalid config for network %s: %w", k, err))
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errdefs.InvalidParameter(multierror.Join(errs...))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
`NetworkingConfig.EndpointSettings`.
|
||||
* `POST /containers/create` and `POST /networks/{id}/connect` will now catch
|
||||
validation errors that were previously only returned during `POST /containers/{id}/start`.
|
||||
These endpoints will also return the full set of validation errors they find,
|
||||
instead of returning only the first one.
|
||||
Note that this change is _unversioned_ and applies to all API versions.
|
||||
|
||||
## v1.43 API changes
|
||||
|
|
Loading…
Add table
Reference in a new issue