mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #163 from aboch/eorr
Provide interface to categorize errors
This commit is contained in:
commit
956fd3f679
27 changed files with 1025 additions and 347 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/docker/libnetwork"
|
||||
"github.com/docker/libnetwork/types"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
|
@ -437,7 +438,7 @@ func findNetwork(c libnetwork.NetworkController, s string, by int) (libnetwork.N
|
|||
panic(fmt.Sprintf("unexpected selector for network search: %d", by))
|
||||
}
|
||||
if err != nil {
|
||||
if err == libnetwork.ErrNoSuchNetwork {
|
||||
if _, ok := err.(libnetwork.ErrNoSuchNetwork); ok {
|
||||
return nil, &responseStatus{Status: "Resource not found: Network", StatusCode: http.StatusNotFound}
|
||||
}
|
||||
return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest}
|
||||
|
@ -463,7 +464,7 @@ func findEndpoint(c libnetwork.NetworkController, ns, es string, nwBy, epBy int)
|
|||
panic(fmt.Sprintf("unexpected selector for endpoint search: %d", epBy))
|
||||
}
|
||||
if err != nil {
|
||||
if err == libnetwork.ErrNoSuchEndpoint {
|
||||
if _, ok := err.(libnetwork.ErrNoSuchEndpoint); ok {
|
||||
return nil, &responseStatus{Status: "Resource not found: Endpoint", StatusCode: http.StatusNotFound}
|
||||
}
|
||||
return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest}
|
||||
|
@ -472,9 +473,26 @@ func findEndpoint(c libnetwork.NetworkController, ns, es string, nwBy, epBy int)
|
|||
}
|
||||
|
||||
func convertNetworkError(err error) *responseStatus {
|
||||
// No real libnetwork error => http error code conversion for now.
|
||||
// Will came in later when new interface for libnetwork error is vailable
|
||||
return &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest}
|
||||
var code int
|
||||
switch err.(type) {
|
||||
case types.BadRequestError:
|
||||
code = http.StatusBadRequest
|
||||
case types.ForbiddenError:
|
||||
code = http.StatusForbidden
|
||||
case types.NotFoundError:
|
||||
code = http.StatusNotFound
|
||||
case types.TimeoutError:
|
||||
code = http.StatusRequestTimeout
|
||||
case types.NotImplementedError:
|
||||
code = http.StatusNotImplemented
|
||||
case types.NoServiceError:
|
||||
code = http.StatusServiceUnavailable
|
||||
case types.InternalError:
|
||||
code = http.StatusInternalServerError
|
||||
default:
|
||||
code = http.StatusInternalServerError
|
||||
}
|
||||
return &responseStatus{Status: err.Error(), StatusCode: code}
|
||||
}
|
||||
|
||||
func writeJSON(w http.ResponseWriter, code int, v interface{}) error {
|
||||
|
|
|
@ -177,8 +177,8 @@ func TestCreateDeleteNetwork(t *testing.T) {
|
|||
if errRsp == &createdResponse {
|
||||
t.Fatalf("Expected to fail but succeeded")
|
||||
}
|
||||
if errRsp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp.StatusCode)
|
||||
if errRsp.StatusCode != http.StatusNotFound {
|
||||
t.Fatalf("Expected StatusNotFound status code, got: %v", errRsp)
|
||||
}
|
||||
|
||||
ops := make(map[string]interface{})
|
||||
|
@ -1389,3 +1389,92 @@ func TestEndToEnd(t *testing.T) {
|
|||
t.Fatalf("Incongruent resource found: %v", epr)
|
||||
}
|
||||
}
|
||||
|
||||
type bre struct{}
|
||||
|
||||
func (b *bre) Error() string {
|
||||
return "I am a bad request error"
|
||||
}
|
||||
func (b *bre) BadRequest() {}
|
||||
|
||||
type nfe struct{}
|
||||
|
||||
func (n *nfe) Error() string {
|
||||
return "I am a not found error"
|
||||
}
|
||||
func (n *nfe) NotFound() {}
|
||||
|
||||
type forb struct{}
|
||||
|
||||
func (f *forb) Error() string {
|
||||
return "I am a bad request error"
|
||||
}
|
||||
func (f *forb) Forbidden() {}
|
||||
|
||||
type notimpl struct{}
|
||||
|
||||
func (nip *notimpl) Error() string {
|
||||
return "I am a not implemented error"
|
||||
}
|
||||
func (nip *notimpl) NotImplemented() {}
|
||||
|
||||
type inter struct{}
|
||||
|
||||
func (it *inter) Error() string {
|
||||
return "I am a internal error"
|
||||
}
|
||||
func (it *inter) Internal() {}
|
||||
|
||||
type tout struct{}
|
||||
|
||||
func (to *tout) Error() string {
|
||||
return "I am a timeout error"
|
||||
}
|
||||
func (to *tout) Timeout() {}
|
||||
|
||||
type noserv struct{}
|
||||
|
||||
func (nos *noserv) Error() string {
|
||||
return "I am a no service error"
|
||||
}
|
||||
func (nos *noserv) NoService() {}
|
||||
|
||||
type notclassified struct{}
|
||||
|
||||
func (noc *notclassified) Error() string {
|
||||
return "I am a non classified error"
|
||||
}
|
||||
|
||||
func TestErrorConversion(t *testing.T) {
|
||||
if convertNetworkError(new(bre)).StatusCode != http.StatusBadRequest {
|
||||
t.Fatalf("Failed to recognize BadRequest error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(nfe)).StatusCode != http.StatusNotFound {
|
||||
t.Fatalf("Failed to recognize NotFound error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(forb)).StatusCode != http.StatusForbidden {
|
||||
t.Fatalf("Failed to recognize Forbidden error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(notimpl)).StatusCode != http.StatusNotImplemented {
|
||||
t.Fatalf("Failed to recognize NotImplemented error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(inter)).StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("Failed to recognize Internal error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(tout)).StatusCode != http.StatusRequestTimeout {
|
||||
t.Fatalf("Failed to recognize Timeout error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(noserv)).StatusCode != http.StatusServiceUnavailable {
|
||||
t.Fatalf("Failed to recognize No Service error")
|
||||
}
|
||||
|
||||
if convertNetworkError(new(notclassified)).StatusCode != http.StatusInternalServerError {
|
||||
t.Fatalf("Failed to recognize not classified error as Internal error")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver)
|
|||
// are network specific and modeled in a generic way.
|
||||
func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) {
|
||||
if name == "" {
|
||||
return nil, ErrInvalidName
|
||||
return nil, ErrInvalidName(name)
|
||||
}
|
||||
// Check if a driver for the specified network type is available
|
||||
c.Lock()
|
||||
|
@ -203,7 +203,7 @@ func (c *controller) WalkNetworks(walker NetworkWalker) {
|
|||
|
||||
func (c *controller) NetworkByName(name string) (Network, error) {
|
||||
if name == "" {
|
||||
return nil, ErrInvalidName
|
||||
return nil, ErrInvalidName(name)
|
||||
}
|
||||
var n Network
|
||||
|
||||
|
@ -218,7 +218,7 @@ func (c *controller) NetworkByName(name string) (Network, error) {
|
|||
c.WalkNetworks(s)
|
||||
|
||||
if n == nil {
|
||||
return nil, ErrNoSuchNetwork
|
||||
return nil, ErrNoSuchNetwork(name)
|
||||
}
|
||||
|
||||
return n, nil
|
||||
|
@ -226,14 +226,14 @@ func (c *controller) NetworkByName(name string) (Network, error) {
|
|||
|
||||
func (c *controller) NetworkByID(id string) (Network, error) {
|
||||
if id == "" {
|
||||
return nil, ErrInvalidID
|
||||
return nil, ErrInvalidID(id)
|
||||
}
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
if n, ok := c.networks[types.UUID(id)]; ok {
|
||||
return n, nil
|
||||
}
|
||||
return nil, ErrNoSuchNetwork
|
||||
return nil, ErrNoSuchNetwork(id)
|
||||
}
|
||||
|
||||
func (c *controller) sandboxAdd(key string, create bool) (sandbox.Sandbox, error) {
|
||||
|
@ -286,13 +286,16 @@ func (c *controller) loadDriver(networkType string) (driverapi.Driver, error) {
|
|||
// As per the design, this Get call will result in remote driver discovery if there is a corresponding plugin available.
|
||||
_, err := plugins.Get(networkType, driverapi.NetworkPluginEndpointType)
|
||||
if err != nil {
|
||||
if err == plugins.ErrNotFound {
|
||||
return nil, types.NotFoundErrorf(err.Error())
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
d, ok := c.drivers[networkType]
|
||||
if !ok {
|
||||
return nil, ErrInvalidNetworkDriver
|
||||
return nil, ErrInvalidNetworkDriver(networkType)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
|
|
@ -1,24 +1,11 @@
|
|||
package driverapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/docker/libnetwork/types"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEndpointExists is returned if more than one endpoint is added to the network
|
||||
ErrEndpointExists = errors.New("Endpoint already exists (Only one endpoint allowed)")
|
||||
// ErrNoNetwork is returned if no network with the specified id exists
|
||||
ErrNoNetwork = errors.New("No network exists")
|
||||
// ErrNoEndpoint is returned if no endpoint with the specified id exists
|
||||
ErrNoEndpoint = errors.New("No endpoint exists")
|
||||
// ErrNotImplemented is returned when a Driver has not implemented an API yet
|
||||
ErrNotImplemented = errors.New("The API is not implemented yet")
|
||||
)
|
||||
|
||||
// NetworkPluginEndpointType represents the Endpoint Type used by Plugin system
|
||||
const NetworkPluginEndpointType = "NetworkDriver"
|
||||
|
||||
|
@ -124,14 +111,6 @@ type JoinInfo interface {
|
|||
SetResolvConfPath(string) error
|
||||
}
|
||||
|
||||
// ErrActiveRegistration represents an error when a driver is registered to a networkType that is previously registered
|
||||
type ErrActiveRegistration string
|
||||
|
||||
// Error interface for ErrActiveRegistration
|
||||
func (ar ErrActiveRegistration) Error() string {
|
||||
return fmt.Sprintf("Driver already registered for type %q", string(ar))
|
||||
}
|
||||
|
||||
// DriverCallback provides a Callback interface for Drivers into LibNetwork
|
||||
type DriverCallback interface {
|
||||
// RegisterDriver provides a way for Remote drivers to dynamically register new NetworkType and associate with a driver instance
|
||||
|
|
56
libnetwork/driverapi/errors.go
Normal file
56
libnetwork/driverapi/errors.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package driverapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrNoNetwork is returned if no network with the specified id exists
|
||||
type ErrNoNetwork string
|
||||
|
||||
func (enn ErrNoNetwork) Error() string {
|
||||
return fmt.Sprintf("No network (%s) exists", string(enn))
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (enn ErrNoNetwork) NotFound() {}
|
||||
|
||||
// ErrEndpointExists is returned if more than one endpoint is added to the network
|
||||
type ErrEndpointExists string
|
||||
|
||||
func (ee ErrEndpointExists) Error() string {
|
||||
return fmt.Sprintf("Endpoint (%s) already exists (Only one endpoint allowed)", string(ee))
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ee ErrEndpointExists) Forbidden() {}
|
||||
|
||||
// ErrNotImplemented is returned when a Driver has not implemented an API yet
|
||||
type ErrNotImplemented struct{}
|
||||
|
||||
func (eni *ErrNotImplemented) Error() string {
|
||||
return "The API is not implemented yet"
|
||||
}
|
||||
|
||||
// NotImplemented denotes the type of this error
|
||||
func (eni *ErrNotImplemented) NotImplemented() {}
|
||||
|
||||
// ErrNoEndpoint is returned if no endpoint with the specified id exists
|
||||
type ErrNoEndpoint string
|
||||
|
||||
func (ene ErrNoEndpoint) Error() string {
|
||||
return fmt.Sprintf("No endpoint (%s) exists", string(ene))
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (ene ErrNoEndpoint) NotFound() {}
|
||||
|
||||
// ErrActiveRegistration represents an error when a driver is registered to a networkType that is previously registered
|
||||
type ErrActiveRegistration string
|
||||
|
||||
// Error interface for ErrActiveRegistration
|
||||
func (ar ErrActiveRegistration) Error() string {
|
||||
return fmt.Sprintf("Driver already registered for type %q", string(ar))
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ar ErrActiveRegistration) Forbidden() {}
|
|
@ -109,7 +109,7 @@ func Init(dc driverapi.DriverCallback) error {
|
|||
// Whatever can be assessed a priori before attempting any programming.
|
||||
func (c *NetworkConfiguration) Validate() error {
|
||||
if c.Mtu < 0 {
|
||||
return ErrInvalidMtu
|
||||
return ErrInvalidMtu(c.Mtu)
|
||||
}
|
||||
|
||||
// If bridge v4 subnet is specified
|
||||
|
@ -118,19 +118,19 @@ func (c *NetworkConfiguration) Validate() error {
|
|||
if c.FixedCIDR != nil {
|
||||
// Check Network address
|
||||
if !c.AddressIPv4.Contains(c.FixedCIDR.IP) {
|
||||
return ErrInvalidContainerSubnet
|
||||
return &ErrInvalidContainerSubnet{}
|
||||
}
|
||||
// Check it is effectively a subset
|
||||
brNetLen, _ := c.AddressIPv4.Mask.Size()
|
||||
cnNetLen, _ := c.FixedCIDR.Mask.Size()
|
||||
if brNetLen > cnNetLen {
|
||||
return ErrInvalidContainerSubnet
|
||||
return &ErrInvalidContainerSubnet{}
|
||||
}
|
||||
}
|
||||
// If default gw is specified, it must be part of bridge subnet
|
||||
if c.DefaultGatewayIPv4 != nil {
|
||||
if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
|
||||
return ErrInvalidGateway
|
||||
return &ErrInvalidGateway{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func (c *NetworkConfiguration) Validate() error {
|
|||
// If default v6 gw is specified, FixedCIDRv6 must be specified and gw must belong to FixedCIDRv6 subnet
|
||||
if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
|
||||
if c.FixedCIDRv6 == nil || !c.FixedCIDRv6.Contains(c.DefaultGatewayIPv6) {
|
||||
return ErrInvalidGateway
|
||||
return &ErrInvalidGateway{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ func (d *driver) Config(option map[string]interface{}) error {
|
|||
defer d.Unlock()
|
||||
|
||||
if d.config != nil {
|
||||
return ErrConfigExists
|
||||
return &ErrConfigExists{}
|
||||
}
|
||||
|
||||
genericData, ok := option[netlabel.GenericData]
|
||||
|
@ -182,7 +182,7 @@ func (d *driver) Config(option map[string]interface{}) error {
|
|||
case *Configuration:
|
||||
config = opt
|
||||
default:
|
||||
return ErrInvalidDriverConfig
|
||||
return &ErrInvalidDriverConfig{}
|
||||
}
|
||||
|
||||
d.config = config
|
||||
|
@ -220,7 +220,7 @@ func parseNetworkOptions(option options.Generic) (*NetworkConfiguration, error)
|
|||
case *NetworkConfiguration:
|
||||
config = opt
|
||||
default:
|
||||
return nil, ErrInvalidNetworkConfig
|
||||
return nil, &ErrInvalidNetworkConfig{}
|
||||
}
|
||||
|
||||
if err := config.Validate(); err != nil {
|
||||
|
@ -247,7 +247,7 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
|
|||
// Sanity checks
|
||||
if d.network != nil {
|
||||
d.Unlock()
|
||||
return ErrNetworkExists
|
||||
return &ErrNetworkExists{}
|
||||
}
|
||||
|
||||
// Create and set network handler in driver
|
||||
|
@ -361,7 +361,7 @@ func (d *driver) DeleteNetwork(nid types.UUID) error {
|
|||
|
||||
// Sanity check
|
||||
if n == nil {
|
||||
err = driverapi.ErrNoNetwork
|
||||
err = driverapi.ErrNoNetwork(nid)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
|
|||
config := n.config
|
||||
d.Unlock()
|
||||
if n == nil {
|
||||
return driverapi.ErrNoNetwork
|
||||
return driverapi.ErrNoNetwork(nid)
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
|
@ -416,7 +416,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
|
|||
|
||||
// Endpoint with that id exists either on desired or other sandbox
|
||||
if ep != nil {
|
||||
return driverapi.ErrEndpointExists
|
||||
return driverapi.ErrEndpointExists(eid)
|
||||
}
|
||||
|
||||
// Try to convert the options to endpoint configuration
|
||||
|
@ -578,7 +578,7 @@ func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
|
|||
config := n.config
|
||||
d.Unlock()
|
||||
if n == nil {
|
||||
return driverapi.ErrNoNetwork
|
||||
return driverapi.ErrNoNetwork(nid)
|
||||
}
|
||||
|
||||
// Sanity Check
|
||||
|
@ -648,7 +648,7 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{},
|
|||
n := d.network
|
||||
d.Unlock()
|
||||
if n == nil {
|
||||
return nil, driverapi.ErrNoNetwork
|
||||
return nil, driverapi.ErrNoNetwork(nid)
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
|
@ -665,7 +665,7 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{},
|
|||
return nil, err
|
||||
}
|
||||
if ep == nil {
|
||||
return nil, driverapi.ErrNoEndpoint
|
||||
return nil, driverapi.ErrNoEndpoint(eid)
|
||||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
|
@ -856,7 +856,7 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfigurat
|
|||
if mac, ok := opt.(net.HardwareAddr); ok {
|
||||
ec.MacAddress = mac
|
||||
} else {
|
||||
return nil, ErrInvalidEndpointConfig
|
||||
return nil, &ErrInvalidEndpointConfig{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -864,7 +864,7 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfigurat
|
|||
if bs, ok := opt.([]types.PortBinding); ok {
|
||||
ec.PortBindings = bs
|
||||
} else {
|
||||
return nil, ErrInvalidEndpointConfig
|
||||
return nil, &ErrInvalidEndpointConfig{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -872,7 +872,7 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfigurat
|
|||
if ports, ok := opt.([]types.TransportPort); ok {
|
||||
ec.ExposedPorts = ports
|
||||
} else {
|
||||
return nil, ErrInvalidEndpointConfig
|
||||
return nil, &ErrInvalidEndpointConfig{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -924,5 +924,5 @@ func generateIfaceName() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
}
|
||||
return "", ErrIfaceName
|
||||
return "", &ErrIfaceName{}
|
||||
}
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrConfigExists error is returned when driver already has a config applied.
|
||||
ErrConfigExists = errors.New("configuration already exists, bridge configuration can be applied only once")
|
||||
|
||||
// ErrInvalidDriverConfig error is returned when Bridge Driver is passed an invalid config
|
||||
ErrInvalidDriverConfig = errors.New("Invalid configuration passed to Bridge Driver")
|
||||
|
||||
// ErrInvalidNetworkConfig error is returned when a network is created on a driver without valid config.
|
||||
ErrInvalidNetworkConfig = errors.New("trying to create a network on a driver without valid config")
|
||||
|
||||
// ErrInvalidContainerConfig error is returned when a endpoint create is attempted with an invalid configuration.
|
||||
ErrInvalidContainerConfig = errors.New("Error in joining a container due to invalid configuration")
|
||||
|
||||
// ErrInvalidEndpointConfig error is returned when a endpoint create is attempted with an invalid endpoint configuration.
|
||||
ErrInvalidEndpointConfig = errors.New("trying to create an endpoint with an invalid endpoint configuration")
|
||||
|
||||
// ErrNetworkExists error is returned when a network already exists and another network is created.
|
||||
ErrNetworkExists = errors.New("network already exists, bridge can only have one network")
|
||||
|
||||
// ErrIfaceName error is returned when a new name could not be generated.
|
||||
ErrIfaceName = errors.New("failed to find name for new interface")
|
||||
|
||||
// ErrNoIPAddr error is returned when bridge has no IPv4 address configured.
|
||||
ErrNoIPAddr = errors.New("bridge has no IPv4 address configured")
|
||||
|
||||
// ErrInvalidGateway is returned when the user provided default gateway (v4/v6) is not not valid.
|
||||
ErrInvalidGateway = errors.New("default gateway ip must be part of the network")
|
||||
|
||||
// ErrInvalidContainerSubnet is returned when the container subnet (FixedCIDR) is not valid.
|
||||
ErrInvalidContainerSubnet = errors.New("container subnet must be a subset of bridge network")
|
||||
|
||||
// ErrInvalidMtu is returned when the user provided MTU is not valid.
|
||||
ErrInvalidMtu = errors.New("invalid MTU number")
|
||||
|
||||
// ErrIPFwdCfg is returned when ip forwarding setup is invoked when the configuration
|
||||
// not enabled.
|
||||
ErrIPFwdCfg = errors.New("unexpected request to enable IP Forwarding")
|
||||
)
|
||||
|
||||
// ErrInvalidPort is returned when the container or host port specified in the port binding is not valid.
|
||||
type ErrInvalidPort string
|
||||
|
||||
func (ip ErrInvalidPort) Error() string {
|
||||
return fmt.Sprintf("invalid transport port: %s", string(ip))
|
||||
}
|
||||
|
||||
// ErrUnsupportedAddressType is returned when the specified address type is not supported.
|
||||
type ErrUnsupportedAddressType string
|
||||
|
||||
func (uat ErrUnsupportedAddressType) Error() string {
|
||||
return fmt.Sprintf("unsupported address type: %s", string(uat))
|
||||
}
|
||||
|
||||
// ErrInvalidAddressBinding is returned when the host address specified in the port binding is not valid.
|
||||
type ErrInvalidAddressBinding string
|
||||
|
||||
func (iab ErrInvalidAddressBinding) Error() string {
|
||||
return fmt.Sprintf("invalid host address in port binding: %s", string(iab))
|
||||
}
|
||||
|
||||
// ActiveEndpointsError is returned when there are
|
||||
// still active endpoints in the network being deleted.
|
||||
type ActiveEndpointsError string
|
||||
|
||||
func (aee ActiveEndpointsError) Error() string {
|
||||
return fmt.Sprintf("network %s has active endpoint", string(aee))
|
||||
}
|
||||
|
||||
// InvalidNetworkIDError is returned when the passed
|
||||
// network id for an existing network is not a known id.
|
||||
type InvalidNetworkIDError string
|
||||
|
||||
func (inie InvalidNetworkIDError) Error() string {
|
||||
return fmt.Sprintf("invalid network id %s", string(inie))
|
||||
}
|
||||
|
||||
// InvalidEndpointIDError is returned when the passed
|
||||
// endpoint id is not valid.
|
||||
type InvalidEndpointIDError string
|
||||
|
||||
func (ieie InvalidEndpointIDError) Error() string {
|
||||
return fmt.Sprintf("invalid endpoint id: %s", string(ieie))
|
||||
}
|
||||
|
||||
// InvalidSandboxIDError is returned when the passed
|
||||
// sandbox id valid.
|
||||
type InvalidSandboxIDError string
|
||||
|
||||
func (isie InvalidSandboxIDError) Error() string {
|
||||
return fmt.Sprintf("invalid sanbox id: %s", string(isie))
|
||||
}
|
||||
|
||||
// EndpointNotFoundError is returned when the no endpoint
|
||||
// with the passed endpoint id is found.
|
||||
type EndpointNotFoundError string
|
||||
|
||||
func (enfe EndpointNotFoundError) Error() string {
|
||||
return fmt.Sprintf("endpoint not found: %s", string(enfe))
|
||||
}
|
||||
|
||||
// NonDefaultBridgeExistError is returned when a non-default
|
||||
// bridge config is passed but it does not already exist.
|
||||
type NonDefaultBridgeExistError string
|
||||
|
||||
func (ndbee NonDefaultBridgeExistError) Error() string {
|
||||
return fmt.Sprintf("bridge device with non default name %s must be created manually", string(ndbee))
|
||||
}
|
||||
|
||||
// FixedCIDRv4Error is returned when fixed-cidrv4 configuration
|
||||
// failed.
|
||||
type FixedCIDRv4Error struct {
|
||||
net *net.IPNet
|
||||
subnet *net.IPNet
|
||||
err error
|
||||
}
|
||||
|
||||
func (fcv4 *FixedCIDRv4Error) Error() string {
|
||||
return fmt.Sprintf("setup FixedCIDRv4 failed for subnet %s in %s: %v", fcv4.subnet, fcv4.net, fcv4.err)
|
||||
}
|
||||
|
||||
// FixedCIDRv6Error is returned when fixed-cidrv6 configuration
|
||||
// failed.
|
||||
type FixedCIDRv6Error struct {
|
||||
net *net.IPNet
|
||||
err error
|
||||
}
|
||||
|
||||
func (fcv6 *FixedCIDRv6Error) Error() string {
|
||||
return fmt.Sprintf("setup FixedCIDRv6 failed for subnet %s in %s: %v", fcv6.net, fcv6.net, fcv6.err)
|
||||
}
|
||||
|
||||
type ipTableCfgError string
|
||||
|
||||
func (name ipTableCfgError) Error() string {
|
||||
return fmt.Sprintf("unexpected request to set IP tables for interface: %s", string(name))
|
||||
}
|
||||
|
||||
type invalidIPTablesCfgError string
|
||||
|
||||
func (action invalidIPTablesCfgError) Error() string {
|
||||
return fmt.Sprintf("Invalid IPTables action '%s'", string(action))
|
||||
}
|
||||
|
||||
// IPv4AddrRangeError is returned when a valid IP address range couldn't be found.
|
||||
type IPv4AddrRangeError string
|
||||
|
||||
func (name IPv4AddrRangeError) Error() string {
|
||||
return fmt.Sprintf("can't find an address range for interface %q", string(name))
|
||||
}
|
||||
|
||||
// IPv4AddrAddError is returned when IPv4 address could not be added to the bridge.
|
||||
type IPv4AddrAddError struct {
|
||||
ip *net.IPNet
|
||||
err error
|
||||
}
|
||||
|
||||
func (ipv4 *IPv4AddrAddError) Error() string {
|
||||
return fmt.Sprintf("failed to add IPv4 address %s to bridge: %v", ipv4.ip, ipv4.err)
|
||||
}
|
||||
|
||||
// IPv6AddrAddError is returned when IPv6 address could not be added to the bridge.
|
||||
type IPv6AddrAddError struct {
|
||||
ip *net.IPNet
|
||||
err error
|
||||
}
|
||||
|
||||
func (ipv6 *IPv6AddrAddError) Error() string {
|
||||
return fmt.Sprintf("failed to add IPv6 address %s to bridge: %v", ipv6.ip, ipv6.err)
|
||||
}
|
||||
|
||||
// IPv4AddrNoMatchError is returned when the bridge's IPv4 address does not match configured.
|
||||
type IPv4AddrNoMatchError struct {
|
||||
ip net.IP
|
||||
cfgIP net.IP
|
||||
}
|
||||
|
||||
func (ipv4 *IPv4AddrNoMatchError) Error() string {
|
||||
return fmt.Sprintf("bridge IPv4 (%s) does not match requested configuration %s", ipv4.ip, ipv4.cfgIP)
|
||||
}
|
||||
|
||||
// IPv6AddrNoMatchError is returned when the bridge's IPv6 address does not match configured.
|
||||
type IPv6AddrNoMatchError net.IPNet
|
||||
|
||||
func (ipv6 *IPv6AddrNoMatchError) Error() string {
|
||||
return fmt.Sprintf("bridge IPv6 addresses do not match the expected bridge configuration %s", (*net.IPNet)(ipv6).String())
|
||||
}
|
||||
|
||||
// InvalidLinkIPAddrError is returned when a link is configured to a container with an invalid ip address
|
||||
type InvalidLinkIPAddrError string
|
||||
|
||||
func (address InvalidLinkIPAddrError) Error() string {
|
||||
return fmt.Sprintf("Cannot link to a container with Invalid IP Address '%s'", string(address))
|
||||
}
|
341
libnetwork/drivers/bridge/errors.go
Normal file
341
libnetwork/drivers/bridge/errors.go
Normal file
|
@ -0,0 +1,341 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
// ErrConfigExists error is returned when driver already has a config applied.
|
||||
type ErrConfigExists struct{}
|
||||
|
||||
func (ece *ErrConfigExists) Error() string {
|
||||
return "configuration already exists, bridge configuration can be applied only once"
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ece *ErrConfigExists) Forbidden() {}
|
||||
|
||||
// ErrInvalidDriverConfig error is returned when Bridge Driver is passed an invalid config
|
||||
type ErrInvalidDriverConfig struct{}
|
||||
|
||||
func (eidc *ErrInvalidDriverConfig) Error() string {
|
||||
return "Invalid configuration passed to Bridge Driver"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eidc *ErrInvalidDriverConfig) BadRequest() {}
|
||||
|
||||
// ErrInvalidNetworkConfig error is returned when a network is created on a driver without valid config.
|
||||
type ErrInvalidNetworkConfig struct{}
|
||||
|
||||
func (einc *ErrInvalidNetworkConfig) Error() string {
|
||||
return "trying to create a network on a driver without valid config"
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (einc *ErrInvalidNetworkConfig) Forbidden() {}
|
||||
|
||||
// ErrInvalidContainerConfig error is returned when a endpoint create is attempted with an invalid configuration.
|
||||
type ErrInvalidContainerConfig struct{}
|
||||
|
||||
func (eicc *ErrInvalidContainerConfig) Error() string {
|
||||
return "Error in joining a container due to invalid configuration"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eicc *ErrInvalidContainerConfig) BadRequest() {}
|
||||
|
||||
// ErrInvalidEndpointConfig error is returned when a endpoint create is attempted with an invalid endpoint configuration.
|
||||
type ErrInvalidEndpointConfig struct{}
|
||||
|
||||
func (eiec *ErrInvalidEndpointConfig) Error() string {
|
||||
return "trying to create an endpoint with an invalid endpoint configuration"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eiec *ErrInvalidEndpointConfig) BadRequest() {}
|
||||
|
||||
// ErrNetworkExists error is returned when a network already exists and another network is created.
|
||||
type ErrNetworkExists struct{}
|
||||
|
||||
func (ene *ErrNetworkExists) Error() string {
|
||||
return "network already exists, bridge can only have one network"
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ene *ErrNetworkExists) Forbidden() {}
|
||||
|
||||
// ErrIfaceName error is returned when a new name could not be generated.
|
||||
type ErrIfaceName struct{}
|
||||
|
||||
func (ein *ErrIfaceName) Error() string {
|
||||
return "failed to find name for new interface"
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (ein *ErrIfaceName) InternalError() {}
|
||||
|
||||
// ErrNoIPAddr error is returned when bridge has no IPv4 address configured.
|
||||
type ErrNoIPAddr struct{}
|
||||
|
||||
func (enip *ErrNoIPAddr) Error() string {
|
||||
return "bridge has no IPv4 address configured"
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (enip *ErrNoIPAddr) InternalError() {}
|
||||
|
||||
// ErrInvalidGateway is returned when the user provided default gateway (v4/v6) is not not valid.
|
||||
type ErrInvalidGateway struct{}
|
||||
|
||||
func (eig *ErrInvalidGateway) Error() string {
|
||||
return "default gateway ip must be part of the network"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eig *ErrInvalidGateway) BadRequest() {}
|
||||
|
||||
// ErrInvalidContainerSubnet is returned when the container subnet (FixedCIDR) is not valid.
|
||||
type ErrInvalidContainerSubnet struct{}
|
||||
|
||||
func (eis *ErrInvalidContainerSubnet) Error() string {
|
||||
return "container subnet must be a subset of bridge network"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eis *ErrInvalidContainerSubnet) BadRequest() {}
|
||||
|
||||
// ErrInvalidMtu is returned when the user provided MTU is not valid.
|
||||
type ErrInvalidMtu int
|
||||
|
||||
func (eim ErrInvalidMtu) Error() string {
|
||||
return fmt.Sprintf("invalid MTU number: %d", int(eim))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eim ErrInvalidMtu) BadRequest() {}
|
||||
|
||||
// ErrIPFwdCfg is returned when ip forwarding setup is invoked when the configuration
|
||||
// not enabled.
|
||||
type ErrIPFwdCfg struct{}
|
||||
|
||||
func (eipf *ErrIPFwdCfg) Error() string {
|
||||
return "unexpected request to enable IP Forwarding"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (eipf *ErrIPFwdCfg) BadRequest() {}
|
||||
|
||||
// ErrInvalidPort is returned when the container or host port specified in the port binding is not valid.
|
||||
type ErrInvalidPort string
|
||||
|
||||
func (ip ErrInvalidPort) Error() string {
|
||||
return fmt.Sprintf("invalid transport port: %s", string(ip))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ip ErrInvalidPort) BadRequest() {}
|
||||
|
||||
// ErrUnsupportedAddressType is returned when the specified address type is not supported.
|
||||
type ErrUnsupportedAddressType string
|
||||
|
||||
func (uat ErrUnsupportedAddressType) Error() string {
|
||||
return fmt.Sprintf("unsupported address type: %s", string(uat))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (uat ErrUnsupportedAddressType) BadRequest() {}
|
||||
|
||||
// ErrInvalidAddressBinding is returned when the host address specified in the port binding is not valid.
|
||||
type ErrInvalidAddressBinding string
|
||||
|
||||
func (iab ErrInvalidAddressBinding) Error() string {
|
||||
return fmt.Sprintf("invalid host address in port binding: %s", string(iab))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (iab ErrInvalidAddressBinding) BadRequest() {}
|
||||
|
||||
// ActiveEndpointsError is returned when there are
|
||||
// still active endpoints in the network being deleted.
|
||||
type ActiveEndpointsError string
|
||||
|
||||
func (aee ActiveEndpointsError) Error() string {
|
||||
return fmt.Sprintf("network %s has active endpoint", string(aee))
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (aee ActiveEndpointsError) Forbidden() {}
|
||||
|
||||
// InvalidNetworkIDError is returned when the passed
|
||||
// network id for an existing network is not a known id.
|
||||
type InvalidNetworkIDError string
|
||||
|
||||
func (inie InvalidNetworkIDError) Error() string {
|
||||
return fmt.Sprintf("invalid network id %s", string(inie))
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (inie InvalidNetworkIDError) NotFound() {}
|
||||
|
||||
// InvalidEndpointIDError is returned when the passed
|
||||
// endpoint id is not valid.
|
||||
type InvalidEndpointIDError string
|
||||
|
||||
func (ieie InvalidEndpointIDError) Error() string {
|
||||
return fmt.Sprintf("invalid endpoint id: %s", string(ieie))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ieie InvalidEndpointIDError) BadRequest() {}
|
||||
|
||||
// InvalidSandboxIDError is returned when the passed
|
||||
// sandbox id is not valid.
|
||||
type InvalidSandboxIDError string
|
||||
|
||||
func (isie InvalidSandboxIDError) Error() string {
|
||||
return fmt.Sprintf("invalid sanbox id: %s", string(isie))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (isie InvalidSandboxIDError) BadRequest() {}
|
||||
|
||||
// EndpointNotFoundError is returned when the no endpoint
|
||||
// with the passed endpoint id is found.
|
||||
type EndpointNotFoundError string
|
||||
|
||||
func (enfe EndpointNotFoundError) Error() string {
|
||||
return fmt.Sprintf("endpoint not found: %s", string(enfe))
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (enfe EndpointNotFoundError) NotFound() {}
|
||||
|
||||
// NonDefaultBridgeExistError is returned when a non-default
|
||||
// bridge config is passed but it does not already exist.
|
||||
type NonDefaultBridgeExistError string
|
||||
|
||||
func (ndbee NonDefaultBridgeExistError) Error() string {
|
||||
return fmt.Sprintf("bridge device with non default name %s must be created manually", string(ndbee))
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ndbee NonDefaultBridgeExistError) Forbidden() {}
|
||||
|
||||
// FixedCIDRv4Error is returned when fixed-cidrv4 configuration
|
||||
// failed.
|
||||
type FixedCIDRv4Error struct {
|
||||
Net *net.IPNet
|
||||
Subnet *net.IPNet
|
||||
Err error
|
||||
}
|
||||
|
||||
func (fcv4 *FixedCIDRv4Error) Error() string {
|
||||
return fmt.Sprintf("setup FixedCIDRv4 failed for subnet %s in %s: %v", fcv4.Subnet, fcv4.Net, fcv4.Err)
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (fcv4 *FixedCIDRv4Error) InternalError() {}
|
||||
|
||||
// FixedCIDRv6Error is returned when fixed-cidrv6 configuration
|
||||
// failed.
|
||||
type FixedCIDRv6Error struct {
|
||||
Net *net.IPNet
|
||||
Err error
|
||||
}
|
||||
|
||||
func (fcv6 *FixedCIDRv6Error) Error() string {
|
||||
return fmt.Sprintf("setup FixedCIDRv6 failed for subnet %s in %s: %v", fcv6.Net, fcv6.Net, fcv6.Err)
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (fcv6 *FixedCIDRv6Error) InternalError() {}
|
||||
|
||||
// IPTableCfgError is returned when an unexpected ip tables configuration is entered
|
||||
type IPTableCfgError string
|
||||
|
||||
func (name IPTableCfgError) Error() string {
|
||||
return fmt.Sprintf("unexpected request to set IP tables for interface: %s", string(name))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (name IPTableCfgError) BadRequest() {}
|
||||
|
||||
// InvalidIPTablesCfgError is returned when an invalid ip tables configuration is entered
|
||||
type InvalidIPTablesCfgError string
|
||||
|
||||
func (action InvalidIPTablesCfgError) Error() string {
|
||||
return fmt.Sprintf("Invalid IPTables action '%s'", string(action))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (action InvalidIPTablesCfgError) BadRequest() {}
|
||||
|
||||
// IPv4AddrRangeError is returned when a valid IP address range couldn't be found.
|
||||
type IPv4AddrRangeError string
|
||||
|
||||
func (name IPv4AddrRangeError) Error() string {
|
||||
return fmt.Sprintf("can't find an address range for interface %q", string(name))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (name IPv4AddrRangeError) BadRequest() {}
|
||||
|
||||
// IPv4AddrAddError is returned when IPv4 address could not be added to the bridge.
|
||||
type IPv4AddrAddError struct {
|
||||
IP *net.IPNet
|
||||
Err error
|
||||
}
|
||||
|
||||
func (ipv4 *IPv4AddrAddError) Error() string {
|
||||
return fmt.Sprintf("failed to add IPv4 address %s to bridge: %v", ipv4.IP, ipv4.Err)
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (ipv4 *IPv4AddrAddError) InternalError() {}
|
||||
|
||||
// IPv6AddrAddError is returned when IPv6 address could not be added to the bridge.
|
||||
type IPv6AddrAddError struct {
|
||||
IP *net.IPNet
|
||||
Err error
|
||||
}
|
||||
|
||||
func (ipv6 *IPv6AddrAddError) Error() string {
|
||||
return fmt.Sprintf("failed to add IPv6 address %s to bridge: %v", ipv6.IP, ipv6.Err)
|
||||
}
|
||||
|
||||
// InternalError denotes the type of this error
|
||||
func (ipv6 *IPv6AddrAddError) InternalError() {}
|
||||
|
||||
// IPv4AddrNoMatchError is returned when the bridge's IPv4 address does not match configured.
|
||||
type IPv4AddrNoMatchError struct {
|
||||
IP net.IP
|
||||
CfgIP net.IP
|
||||
}
|
||||
|
||||
func (ipv4 *IPv4AddrNoMatchError) Error() string {
|
||||
return fmt.Sprintf("bridge IPv4 (%s) does not match requested configuration %s", ipv4.IP, ipv4.CfgIP)
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ipv4 *IPv4AddrNoMatchError) BadRequest() {}
|
||||
|
||||
// IPv6AddrNoMatchError is returned when the bridge's IPv6 address does not match configured.
|
||||
type IPv6AddrNoMatchError net.IPNet
|
||||
|
||||
func (ipv6 *IPv6AddrNoMatchError) Error() string {
|
||||
return fmt.Sprintf("bridge IPv6 addresses do not match the expected bridge configuration %s", (*net.IPNet)(ipv6).String())
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ipv6 *IPv6AddrNoMatchError) BadRequest() {}
|
||||
|
||||
// InvalidLinkIPAddrError is returned when a link is configured to a container with an invalid ip address
|
||||
type InvalidLinkIPAddrError string
|
||||
|
||||
func (address InvalidLinkIPAddrError) Error() string {
|
||||
return fmt.Sprintf("Cannot link to a container with Invalid IP Address '%s'", string(address))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (address InvalidLinkIPAddrError) BadRequest() {}
|
|
@ -57,7 +57,7 @@ func linkContainers(action, parentIP, childIP string, ports []types.TransportPor
|
|||
case "-D":
|
||||
nfAction = iptables.Delete
|
||||
default:
|
||||
return invalidIPTablesCfgError(action)
|
||||
return InvalidIPTablesCfgError(action)
|
||||
}
|
||||
|
||||
ip1 := net.ParseIP(parentIP)
|
||||
|
|
|
@ -125,8 +125,8 @@ func TestLinkCreateTwo(t *testing.T) {
|
|||
te2 := &testEndpoint{ifaces: []*testInterface{}}
|
||||
err = d.CreateEndpoint("dummy", "ep", te2, nil)
|
||||
if err != nil {
|
||||
if err != driverapi.ErrEndpointExists {
|
||||
t.Fatalf("Failed with a wrong error :%s", err.Error())
|
||||
if _, ok := err.(driverapi.ErrEndpointExists); !ok {
|
||||
t.Fatalf("Failed with a wrong error: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
t.Fatalf("Expected to fail while trying to add same endpoint twice")
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package bridge
|
||||
|
||||
import log "github.com/Sirupsen/logrus"
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
func setupFixedCIDRv4(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
addrv4, _, err := i.addresses()
|
||||
|
@ -10,7 +12,7 @@ func setupFixedCIDRv4(config *NetworkConfiguration, i *bridgeInterface) error {
|
|||
|
||||
log.Debugf("Using IPv4 subnet: %v", config.FixedCIDR)
|
||||
if err := ipAllocator.RegisterSubnet(addrv4.IPNet, config.FixedCIDR); err != nil {
|
||||
return &FixedCIDRv4Error{subnet: config.FixedCIDR, net: addrv4.IPNet, err: err}
|
||||
return &FixedCIDRv4Error{Subnet: config.FixedCIDR, Net: addrv4.IPNet, Err: err}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package bridge
|
||||
|
||||
import log "github.com/Sirupsen/logrus"
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
func setupFixedCIDRv6(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
log.Debugf("Using IPv6 subnet: %v", config.FixedCIDRv6)
|
||||
if err := ipAllocator.RegisterSubnet(config.FixedCIDRv6, config.FixedCIDRv6); err != nil {
|
||||
return &FixedCIDRv6Error{net: config.FixedCIDRv6, err: err}
|
||||
return &FixedCIDRv6Error{Net: config.FixedCIDRv6, Err: err}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -13,7 +13,7 @@ const (
|
|||
func setupIPForwarding(config *Configuration) error {
|
||||
// Sanity Check
|
||||
if config.EnableIPForwarding == false {
|
||||
return ErrIPFwdCfg
|
||||
return &ErrIPFwdCfg{}
|
||||
}
|
||||
|
||||
// Enable IPv4 forwarding
|
||||
|
|
|
@ -47,7 +47,7 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
|
|||
t.Fatal("Setup IP forwarding was expected to fail")
|
||||
}
|
||||
|
||||
if err != ErrIPFwdCfg {
|
||||
if _, ok := err.(*ErrIPFwdCfg); !ok {
|
||||
t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ const (
|
|||
func setupIPTables(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
// Sanity check.
|
||||
if config.EnableIPTables == false {
|
||||
return ipTableCfgError(config.BridgeName)
|
||||
return IPTableCfgError(config.BridgeName)
|
||||
}
|
||||
|
||||
hairpinMode := !config.EnableUserlandProxy
|
||||
|
|
|
@ -71,7 +71,7 @@ func setupBridgeIPv4(config *NetworkConfiguration, i *bridgeInterface) error {
|
|||
|
||||
log.Debugf("Creating bridge interface %q with network %s", config.BridgeName, bridgeIPv4)
|
||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
||||
return &IPv4AddrAddError{ip: bridgeIPv4, err: err}
|
||||
return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
|
||||
}
|
||||
|
||||
// Store bridge network and default gateway
|
||||
|
@ -114,7 +114,7 @@ func electBridgeIPv4(config *NetworkConfiguration) (*net.IPNet, error) {
|
|||
|
||||
func setupGatewayIPv4(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
|
||||
return ErrInvalidGateway
|
||||
return &ErrInvalidGateway{}
|
||||
}
|
||||
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
|
||||
return err
|
||||
|
|
|
@ -37,7 +37,7 @@ func setupBridgeIPv6(config *NetworkConfiguration, i *bridgeInterface) error {
|
|||
// Add the default link local ipv6 address if it doesn't exist
|
||||
if !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
|
||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
|
||||
return &IPv6AddrAddError{ip: bridgeIPv6, err: err}
|
||||
return &IPv6AddrAddError{IP: bridgeIPv6, Err: err}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,10 +50,10 @@ func setupBridgeIPv6(config *NetworkConfiguration, i *bridgeInterface) error {
|
|||
|
||||
func setupGatewayIPv6(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
if config.FixedCIDRv6 == nil {
|
||||
return ErrInvalidContainerSubnet
|
||||
return &ErrInvalidContainerSubnet{}
|
||||
}
|
||||
if !config.FixedCIDRv6.Contains(config.DefaultGatewayIPv6) {
|
||||
return ErrInvalidGateway
|
||||
return &ErrInvalidGateway{}
|
||||
}
|
||||
if _, err := ipAllocator.RequestIP(config.FixedCIDRv6, config.DefaultGatewayIPv6); err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package bridge
|
||||
|
||||
import "github.com/vishvananda/netlink"
|
||||
import (
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func setupVerifyAndReconcile(config *NetworkConfiguration, i *bridgeInterface) error {
|
||||
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
||||
|
@ -11,12 +13,12 @@ func setupVerifyAndReconcile(config *NetworkConfiguration, i *bridgeInterface) e
|
|||
|
||||
// Verify that the bridge does have an IPv4 address.
|
||||
if addrv4.IPNet == nil {
|
||||
return ErrNoIPAddr
|
||||
return &ErrNoIPAddr{}
|
||||
}
|
||||
|
||||
// Verify that the bridge IPv4 address matches the requested configuration.
|
||||
if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
|
||||
return &IPv4AddrNoMatchError{ip: addrv4.IP, cfgIP: config.AddressIPv4.IP}
|
||||
return &IPv4AddrNoMatchError{IP: addrv4.IP, CfgIP: config.AddressIPv4.IP}
|
||||
}
|
||||
|
||||
// Verify that one of the bridge IPv6 addresses matches the requested
|
||||
|
|
|
@ -31,37 +31,37 @@ func Init(dc driverapi.DriverCallback) error {
|
|||
}
|
||||
|
||||
func (d *driver) Config(option map[string]interface{}) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) DeleteNetwork(nid types.UUID) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, error) {
|
||||
return nil, driverapi.ErrNotImplemented
|
||||
return nil, &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
// Join method is invoked when a Sandbox is attached to an endpoint.
|
||||
func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
// Leave method is invoked when a Sandbox detaches from an endpoint.
|
||||
func (d *driver) Leave(nid, eid types.UUID) error {
|
||||
return driverapi.ErrNotImplemented
|
||||
return &driverapi.ErrNotImplemented{}
|
||||
}
|
||||
|
||||
func (d *driver) Type() string {
|
||||
|
|
|
@ -216,7 +216,7 @@ func (ep *endpoint) Join(containerID string, options ...EndpointOption) (*Contai
|
|||
ep.Lock()
|
||||
if ep.container != nil {
|
||||
ep.Unlock()
|
||||
return nil, ErrInvalidJoin
|
||||
return nil, ErrInvalidJoin{}
|
||||
}
|
||||
|
||||
ep.container = &containerInfo{
|
||||
|
@ -334,7 +334,7 @@ func (ep *endpoint) Leave(containerID string, options ...EndpointOption) error {
|
|||
if container == nil || container.id == "" ||
|
||||
containerID == "" || container.id != containerID {
|
||||
if container == nil {
|
||||
err = ErrNoContainer
|
||||
err = ErrNoContainer{}
|
||||
} else {
|
||||
err = InvalidContainerIDError(containerID)
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ func (ep *endpoint) buildHostsFiles() error {
|
|||
ep.Unlock()
|
||||
|
||||
if container == nil {
|
||||
return ErrNoContainer
|
||||
return ErrNoContainer{}
|
||||
}
|
||||
|
||||
if container.config.hostsPath == "" {
|
||||
|
@ -462,7 +462,7 @@ func (ep *endpoint) updateParentHosts() error {
|
|||
ep.Unlock()
|
||||
|
||||
if container == nil {
|
||||
return ErrNoContainer
|
||||
return ErrNoContainer{}
|
||||
}
|
||||
|
||||
for _, update := range container.config.parentUpdates {
|
||||
|
@ -495,7 +495,7 @@ func (ep *endpoint) updateDNS(resolvConf []byte) error {
|
|||
ep.Unlock()
|
||||
|
||||
if container == nil {
|
||||
return ErrNoContainer
|
||||
return ErrNoContainer{}
|
||||
}
|
||||
|
||||
oldHash := []byte{}
|
||||
|
@ -573,7 +573,7 @@ func (ep *endpoint) setupDNS() error {
|
|||
ep.Unlock()
|
||||
|
||||
if container == nil {
|
||||
return ErrNoContainer
|
||||
return ErrNoContainer{}
|
||||
}
|
||||
|
||||
if container.config.resolvConfPath == "" {
|
||||
|
|
|
@ -1,34 +1,83 @@
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoSuchNetwork is returned when a network query finds no result
|
||||
ErrNoSuchNetwork = errors.New("network not found")
|
||||
// ErrNoSuchEndpoint is returned when a endpoint query finds no result
|
||||
ErrNoSuchEndpoint = errors.New("endpoint not found")
|
||||
// ErrNilNetworkDriver is returned if a nil network driver
|
||||
// is passed to NewNetwork api.
|
||||
ErrNilNetworkDriver = errors.New("nil NetworkDriver instance")
|
||||
// ErrInvalidNetworkDriver is returned if an invalid driver
|
||||
// instance is passed.
|
||||
ErrInvalidNetworkDriver = errors.New("invalid driver bound to network")
|
||||
// ErrInvalidJoin is returned if a join is attempted on an endpoint
|
||||
// which already has a container joined.
|
||||
ErrInvalidJoin = errors.New("a container has already joined the endpoint")
|
||||
// ErrNoContainer is returned when the endpoint has no container
|
||||
// attached to it.
|
||||
ErrNoContainer = errors.New("no container attached to the endpoint")
|
||||
// ErrInvalidID is returned when a query-by-id method is being invoked
|
||||
// with an empty id parameter
|
||||
ErrInvalidID = errors.New("invalid ID")
|
||||
// ErrInvalidName is returned when a query-by-name or resource create method is
|
||||
// invoked with an empty name parameter
|
||||
ErrInvalidName = errors.New("invalid Name")
|
||||
)
|
||||
// ErrNoSuchNetwork is returned when a network query finds no result
|
||||
type ErrNoSuchNetwork string
|
||||
|
||||
func (nsn ErrNoSuchNetwork) Error() string {
|
||||
return fmt.Sprintf("network %s not found", string(nsn))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (nsn ErrNoSuchNetwork) BadRequest() {}
|
||||
|
||||
// ErrNoSuchEndpoint is returned when a endpoint query finds no result
|
||||
type ErrNoSuchEndpoint string
|
||||
|
||||
func (nse ErrNoSuchEndpoint) Error() string {
|
||||
return fmt.Sprintf("endpoint %s not found", string(nse))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (nse ErrNoSuchEndpoint) BadRequest() {}
|
||||
|
||||
// ErrInvalidNetworkDriver is returned if an invalid driver
|
||||
// name is passed.
|
||||
type ErrInvalidNetworkDriver string
|
||||
|
||||
func (ind ErrInvalidNetworkDriver) Error() string {
|
||||
return fmt.Sprintf("invalid driver bound to network: %s", string(ind))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ind ErrInvalidNetworkDriver) BadRequest() {}
|
||||
|
||||
// ErrInvalidJoin is returned if a join is attempted on an endpoint
|
||||
// which already has a container joined.
|
||||
type ErrInvalidJoin struct{}
|
||||
|
||||
func (ij ErrInvalidJoin) Error() string {
|
||||
return "a container has already joined the endpoint"
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ij ErrInvalidJoin) BadRequest() {}
|
||||
|
||||
// ErrNoContainer is returned when the endpoint has no container
|
||||
// attached to it.
|
||||
type ErrNoContainer struct{}
|
||||
|
||||
func (nc ErrNoContainer) Error() string {
|
||||
return "a container has already joined the endpoint"
|
||||
}
|
||||
|
||||
// Maskable denotes the type of this error
|
||||
func (nc ErrNoContainer) Maskable() {}
|
||||
|
||||
// ErrInvalidID is returned when a query-by-id method is being invoked
|
||||
// with an empty id parameter
|
||||
type ErrInvalidID string
|
||||
|
||||
func (ii ErrInvalidID) Error() string {
|
||||
return fmt.Sprintf("invalid id: %s", string(ii))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (ii ErrInvalidID) BadRequest() {}
|
||||
|
||||
// ErrInvalidName is returned when a query-by-name or resource create method is
|
||||
// invoked with an empty name parameter
|
||||
type ErrInvalidName string
|
||||
|
||||
func (in ErrInvalidName) Error() string {
|
||||
return fmt.Sprintf("invalid name: %s", string(in))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (in ErrInvalidName) BadRequest() {}
|
||||
|
||||
// NetworkTypeError type is returned when the network type string is not
|
||||
// known to libnetwork.
|
||||
|
@ -38,13 +87,19 @@ func (nt NetworkTypeError) Error() string {
|
|||
return fmt.Sprintf("unknown driver %q", string(nt))
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (nt NetworkTypeError) NotFound() {}
|
||||
|
||||
// NetworkNameError is returned when a network with the same name already exists.
|
||||
type NetworkNameError string
|
||||
|
||||
func (name NetworkNameError) Error() string {
|
||||
return fmt.Sprintf("network with name %s already exists", string(name))
|
||||
func (nnr NetworkNameError) Error() string {
|
||||
return fmt.Sprintf("network with name %s already exists", string(nnr))
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (nnr NetworkNameError) Forbidden() {}
|
||||
|
||||
// UnknownNetworkError is returned when libnetwork could not find in it's database
|
||||
// a network with the same name and id.
|
||||
type UnknownNetworkError struct {
|
||||
|
@ -56,6 +111,9 @@ func (une *UnknownNetworkError) Error() string {
|
|||
return fmt.Sprintf("unknown network %s id %s", une.name, une.id)
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (une *UnknownNetworkError) NotFound() {}
|
||||
|
||||
// ActiveEndpointsError is returned when a network is deleted which has active
|
||||
// endpoints in it.
|
||||
type ActiveEndpointsError struct {
|
||||
|
@ -67,6 +125,9 @@ func (aee *ActiveEndpointsError) Error() string {
|
|||
return fmt.Sprintf("network with name %s id %s has active endpoints", aee.name, aee.id)
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (aee *ActiveEndpointsError) Forbidden() {}
|
||||
|
||||
// UnknownEndpointError is returned when libnetwork could not find in it's database
|
||||
// an endpoint with the same name and id.
|
||||
type UnknownEndpointError struct {
|
||||
|
@ -78,6 +139,9 @@ func (uee *UnknownEndpointError) Error() string {
|
|||
return fmt.Sprintf("unknown endpoint %s id %s", uee.name, uee.id)
|
||||
}
|
||||
|
||||
// NotFound denotes the type of this error
|
||||
func (uee *UnknownEndpointError) NotFound() {}
|
||||
|
||||
// ActiveContainerError is returned when an endpoint is deleted which has active
|
||||
// containers attached to it.
|
||||
type ActiveContainerError struct {
|
||||
|
@ -89,6 +153,9 @@ func (ace *ActiveContainerError) Error() string {
|
|||
return fmt.Sprintf("endpoint with name %s id %s has active containers", ace.name, ace.id)
|
||||
}
|
||||
|
||||
// Forbidden denotes the type of this error
|
||||
func (ace *ActiveContainerError) Forbidden() {}
|
||||
|
||||
// InvalidContainerIDError is returned when an invalid container id is passed
|
||||
// in Join/Leave
|
||||
type InvalidContainerIDError string
|
||||
|
@ -96,3 +163,6 @@ type InvalidContainerIDError string
|
|||
func (id InvalidContainerIDError) Error() string {
|
||||
return fmt.Sprintf("invalid container id %s", string(id))
|
||||
}
|
||||
|
||||
// BadRequest denotes the type of this error
|
||||
func (id InvalidContainerIDError) BadRequest() {}
|
||||
|
|
51
libnetwork/errors_test.go
Normal file
51
libnetwork/errors_test.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/libnetwork/types"
|
||||
)
|
||||
|
||||
func TestErrorInterfaces(t *testing.T) {
|
||||
|
||||
badRequestErrorList := []error{ErrInvalidID(""), ErrInvalidName(""), ErrInvalidJoin{}, ErrInvalidNetworkDriver(""), InvalidContainerIDError(""), ErrNoSuchNetwork(""), ErrNoSuchEndpoint("")}
|
||||
for _, err := range badRequestErrorList {
|
||||
switch u := err.(type) {
|
||||
case types.BadRequestError:
|
||||
return
|
||||
default:
|
||||
t.Fatalf("Failed to detect err %v is of type BadRequestError. Got type: %T", err, u)
|
||||
}
|
||||
}
|
||||
|
||||
maskableErrorList := []error{ErrNoContainer{}}
|
||||
for _, err := range maskableErrorList {
|
||||
switch u := err.(type) {
|
||||
case types.MaskableError:
|
||||
return
|
||||
default:
|
||||
t.Fatalf("Failed to detect err %v is of type MaskableError. Got type: %T", err, u)
|
||||
}
|
||||
}
|
||||
|
||||
notFoundErrorList := []error{NetworkTypeError(""), &UnknownNetworkError{}, &UnknownEndpointError{}}
|
||||
for _, err := range notFoundErrorList {
|
||||
switch u := err.(type) {
|
||||
case types.NotFoundError:
|
||||
return
|
||||
default:
|
||||
t.Fatalf("Failed to detect err %v is of type NotFoundError. Got type: %T", err, u)
|
||||
}
|
||||
}
|
||||
|
||||
forbiddenErrorList := []error{NetworkTypeError(""), &UnknownNetworkError{}, &UnknownEndpointError{}}
|
||||
for _, err := range forbiddenErrorList {
|
||||
switch u := err.(type) {
|
||||
case types.ForbiddenError:
|
||||
return
|
||||
default:
|
||||
t.Fatalf("Failed to detect err %v is of type ForbiddenError. Got type: %T", err, u)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ import (
|
|||
_ "github.com/docker/libnetwork/netutils"
|
||||
)
|
||||
|
||||
const chainName = "DOCKER-TEST"
|
||||
const chainName = "DOCKEREST"
|
||||
|
||||
var natChain *Chain
|
||||
var filterChain *Chain
|
||||
|
|
|
@ -290,7 +290,7 @@ func TestNilRemoteDriver(t *testing.T) {
|
|||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if err != plugins.ErrNotFound {
|
||||
if _, ok := err.(types.NotFoundError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -338,8 +338,9 @@ func TestNetworkName(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidName {
|
||||
t.Fatal("Expected to fail with ErrInvalidName error")
|
||||
|
||||
if _, ok := err.(libnetwork.ErrInvalidName); !ok {
|
||||
t.Fatalf("Expected to fail with ErrInvalidName error. Got %v", err)
|
||||
}
|
||||
|
||||
networkName := "testnetwork"
|
||||
|
@ -475,8 +476,8 @@ func TestUnknownEndpoint(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidName {
|
||||
t.Fatal("Expected to fail with ErrInvalidName error")
|
||||
if _, ok := err.(libnetwork.ErrInvalidName); !ok {
|
||||
t.Fatalf("Expected to fail with ErrInvalidName error. Actual error: %v", err)
|
||||
}
|
||||
|
||||
ep, err := network.CreateEndpoint("testep")
|
||||
|
@ -613,15 +614,15 @@ func TestControllerQuery(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatalf("NetworkByName() succeeded with invalid target name")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidName {
|
||||
t.Fatalf("NetworkByName() failed with unexpected error: %v", err)
|
||||
if _, ok := err.(libnetwork.ErrInvalidName); !ok {
|
||||
t.Fatalf("Expected NetworkByName() to fail with ErrInvalidName error. Got: %v", err)
|
||||
}
|
||||
|
||||
_, err = controller.NetworkByID("")
|
||||
if err == nil {
|
||||
t.Fatalf("NetworkByID() succeeded with invalid target id")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidID {
|
||||
if _, ok := err.(libnetwork.ErrInvalidID); !ok {
|
||||
t.Fatalf("NetworkByID() failed with unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -629,7 +630,7 @@ func TestControllerQuery(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatalf("Unexpected success for NetworkByID(): %v", g)
|
||||
}
|
||||
if err != libnetwork.ErrNoSuchNetwork {
|
||||
if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
|
||||
t.Fatalf("NetworkByID() failed with unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -695,15 +696,15 @@ func TestNetworkQuery(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatalf("EndpointByName() succeeded with invalid target name")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidName {
|
||||
t.Fatalf("EndpointByName() failed with unexpected error: %v", err)
|
||||
if _, ok := err.(libnetwork.ErrInvalidName); !ok {
|
||||
t.Fatalf("Expected EndpointByName() to fail with ErrInvalidName error. Got: %v", err)
|
||||
}
|
||||
|
||||
e, err = net1.EndpointByName("IamNotAnEndpoint")
|
||||
if err == nil {
|
||||
t.Fatalf("EndpointByName() succeeded with unknown target name")
|
||||
}
|
||||
if err != libnetwork.ErrNoSuchEndpoint {
|
||||
if _, ok := err.(libnetwork.ErrNoSuchEndpoint); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if e != nil {
|
||||
|
@ -722,7 +723,7 @@ func TestNetworkQuery(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatalf("EndpointByID() succeeded with invalid target id")
|
||||
}
|
||||
if err != libnetwork.ErrInvalidID {
|
||||
if _, ok := err.(libnetwork.ErrInvalidID); !ok {
|
||||
t.Fatalf("EndpointByID() failed with unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -891,7 +892,7 @@ func TestEndpointMultipleJoins(t *testing.T) {
|
|||
t.Fatal("Expected to fail multiple joins for the same endpoint")
|
||||
}
|
||||
|
||||
if err != libnetwork.ErrInvalidJoin {
|
||||
if _, ok := err.(libnetwork.ErrInvalidJoin); !ok {
|
||||
t.Fatalf("Failed for unexpected reason: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -917,7 +918,7 @@ func TestEndpointInvalidLeave(t *testing.T) {
|
|||
}
|
||||
|
||||
if _, ok := err.(libnetwork.InvalidContainerIDError); !ok {
|
||||
if err != libnetwork.ErrNoContainer {
|
||||
if _, ok := err.(libnetwork.ErrNoContainer); !ok {
|
||||
t.Fatalf("Failed for unexpected reason: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -1297,8 +1298,10 @@ func TestValidRemoteDriver(t *testing.T) {
|
|||
|
||||
_, err = controller.NewNetwork("valid-network-driver", "dummy",
|
||||
libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
|
||||
if err != nil && err != driverapi.ErrNotImplemented {
|
||||
t.Fatal(err)
|
||||
if err != nil {
|
||||
if _, ok := err.(*driverapi.ErrNotImplemented); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,8 +1374,10 @@ func parallelJoin(t *testing.T, ep libnetwork.Endpoint, thrNumber int) {
|
|||
_, err := ep.Join("racing_container")
|
||||
runtime.LockOSThread()
|
||||
if err != nil {
|
||||
if err != libnetwork.ErrNoContainer && err != libnetwork.ErrInvalidJoin {
|
||||
t.Fatal(err)
|
||||
if _, ok := err.(libnetwork.ErrNoContainer); !ok {
|
||||
if _, ok := err.(libnetwork.ErrInvalidJoin); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
debugf("JE%d(%v).", thrNumber, err)
|
||||
}
|
||||
|
@ -1384,8 +1389,10 @@ func parallelLeave(t *testing.T, ep libnetwork.Endpoint, thrNumber int) {
|
|||
err := ep.Leave("racing_container")
|
||||
runtime.LockOSThread()
|
||||
if err != nil {
|
||||
if err != libnetwork.ErrNoContainer && err != libnetwork.ErrInvalidJoin {
|
||||
t.Fatal(err)
|
||||
if _, ok := err.(libnetwork.ErrNoContainer); !ok {
|
||||
if _, ok := err.(libnetwork.ErrInvalidJoin); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
debugf("LE%d(%v).", thrNumber, err)
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ func (n *network) Delete() error {
|
|||
|
||||
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
|
||||
if name == "" {
|
||||
return nil, ErrInvalidName
|
||||
return nil, ErrInvalidName(name)
|
||||
}
|
||||
ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})}
|
||||
ep.id = types.UUID(stringid.GenerateRandomID())
|
||||
|
@ -173,7 +173,7 @@ func (n *network) WalkEndpoints(walker EndpointWalker) {
|
|||
|
||||
func (n *network) EndpointByName(name string) (Endpoint, error) {
|
||||
if name == "" {
|
||||
return nil, ErrInvalidName
|
||||
return nil, ErrInvalidName(name)
|
||||
}
|
||||
var e Endpoint
|
||||
|
||||
|
@ -188,7 +188,7 @@ func (n *network) EndpointByName(name string) (Endpoint, error) {
|
|||
n.WalkEndpoints(s)
|
||||
|
||||
if e == nil {
|
||||
return nil, ErrNoSuchEndpoint
|
||||
return nil, ErrNoSuchEndpoint(name)
|
||||
}
|
||||
|
||||
return e, nil
|
||||
|
@ -196,12 +196,12 @@ func (n *network) EndpointByName(name string) (Endpoint, error) {
|
|||
|
||||
func (n *network) EndpointByID(id string) (Endpoint, error) {
|
||||
if id == "" {
|
||||
return nil, ErrInvalidID
|
||||
return nil, ErrInvalidID(id)
|
||||
}
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
if e, ok := n.endpoints[types.UUID(id)]; ok {
|
||||
return e, nil
|
||||
}
|
||||
return nil, ErrNoSuchEndpoint
|
||||
return nil, ErrNoSuchEndpoint(id)
|
||||
}
|
||||
|
|
|
@ -11,13 +11,6 @@ import (
|
|||
// UUID represents a globally unique ID of various resources like network and endpoint
|
||||
type UUID string
|
||||
|
||||
// ErrInvalidProtocolBinding is returned when the port binding protocol is not valid.
|
||||
type ErrInvalidProtocolBinding string
|
||||
|
||||
func (ipb ErrInvalidProtocolBinding) Error() string {
|
||||
return fmt.Sprintf("invalid transport protocol: %s", string(ipb))
|
||||
}
|
||||
|
||||
// TransportPort represent a local Layer 4 endpoint
|
||||
type TransportPort struct {
|
||||
Proto Protocol
|
||||
|
@ -110,6 +103,13 @@ func (p *PortBinding) Equal(o *PortBinding) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// ErrInvalidProtocolBinding is returned when the port binding protocol is not valid.
|
||||
type ErrInvalidProtocolBinding string
|
||||
|
||||
func (ipb ErrInvalidProtocolBinding) Error() string {
|
||||
return fmt.Sprintf("invalid transport protocol: %s", string(ipb))
|
||||
}
|
||||
|
||||
const (
|
||||
// ICMP is for the ICMP ip protocol
|
||||
ICMP = 1
|
||||
|
@ -183,3 +183,163 @@ func CompareIPNet(a, b *net.IPNet) bool {
|
|||
}
|
||||
return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Well-known Error Interfaces
|
||||
******************************/
|
||||
|
||||
// MaskableError is an interface for errors which can be ignored by caller
|
||||
type MaskableError interface {
|
||||
// Maskable makes implementer into MaskableError type
|
||||
Maskable()
|
||||
}
|
||||
|
||||
// BadRequestError is an interface for errors originated by a bad request
|
||||
type BadRequestError interface {
|
||||
// BadRequest makes implementer into BadRequestError type
|
||||
BadRequest()
|
||||
}
|
||||
|
||||
// NotFoundError is an interface for errors raised because a needed resource is not available
|
||||
type NotFoundError interface {
|
||||
// NotFound makes implementer into NotFoundError type
|
||||
NotFound()
|
||||
}
|
||||
|
||||
// ForbiddenError is an interface for errors which denote an valid request that cannot be honored
|
||||
type ForbiddenError interface {
|
||||
// Forbidden makes implementer into ForbiddenError type
|
||||
Forbidden()
|
||||
}
|
||||
|
||||
// NoServiceError is an interface for errors returned when the required service is not available
|
||||
type NoServiceError interface {
|
||||
// NoService makes implementer into NoServiceError type
|
||||
NoService()
|
||||
}
|
||||
|
||||
// TimeoutError is an interface for errors raised because of timeout
|
||||
type TimeoutError interface {
|
||||
// Timeout makes implementer into TimeoutError type
|
||||
Timeout()
|
||||
}
|
||||
|
||||
// NotImplementedError is an interface for errors raised because of requested functionality is not yet implemented
|
||||
type NotImplementedError interface {
|
||||
// NotImplemented makes implementer into NotImplementedError type
|
||||
NotImplemented()
|
||||
}
|
||||
|
||||
// InternalError is an interface for errors raised because of an internal error
|
||||
type InternalError interface {
|
||||
// Internal makes implementer into InternalError type
|
||||
Internal()
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Weel-known Error Formatters
|
||||
******************************/
|
||||
|
||||
// BadRequestErrorf creates an instance of BadRequestError
|
||||
func BadRequestErrorf(format string, params ...interface{}) error {
|
||||
return badRequest(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// NotFoundErrorf creates an instance of NotFoundError
|
||||
func NotFoundErrorf(format string, params ...interface{}) error {
|
||||
return notFound(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// ForbiddenErrorf creates an instance of ForbiddenError
|
||||
func ForbiddenErrorf(format string, params ...interface{}) error {
|
||||
return forbidden(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// NoServiceErrorf creates an instance of NoServiceError
|
||||
func NoServiceErrorf(format string, params ...interface{}) error {
|
||||
return noService(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// NotImplementedErrorf creates an instance of NotImplementedError
|
||||
func NotImplementedErrorf(format string, params ...interface{}) error {
|
||||
return notImpl(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// TimeoutErrorf creates an instance of TimeoutError
|
||||
func TimeoutErrorf(format string, params ...interface{}) error {
|
||||
return timeout(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// InternalErrorf creates an instance of InternalError
|
||||
func InternalErrorf(format string, params ...interface{}) error {
|
||||
return internal(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
// InternalMaskableErrorf creates an instance of InternalError and MaskableError
|
||||
func InternalMaskableErrorf(format string, params ...interface{}) error {
|
||||
return maskInternal(fmt.Sprintf(format, params...))
|
||||
}
|
||||
|
||||
/***********************
|
||||
* Internal Error Types
|
||||
***********************/
|
||||
type badRequest string
|
||||
|
||||
func (br badRequest) Error() string {
|
||||
return string(br)
|
||||
}
|
||||
func (br badRequest) BadRequest() {}
|
||||
|
||||
type maskBadRequest string
|
||||
|
||||
type notFound string
|
||||
|
||||
func (nf notFound) Error() string {
|
||||
return string(nf)
|
||||
}
|
||||
func (nf notFound) NotFound() {}
|
||||
|
||||
type forbidden string
|
||||
|
||||
func (frb forbidden) Error() string {
|
||||
return string(frb)
|
||||
}
|
||||
func (frb forbidden) Forbidden() {}
|
||||
|
||||
type noService string
|
||||
|
||||
func (ns noService) Error() string {
|
||||
return string(ns)
|
||||
}
|
||||
func (ns noService) NoService() {}
|
||||
|
||||
type maskNoService string
|
||||
|
||||
type timeout string
|
||||
|
||||
func (to timeout) Error() string {
|
||||
return string(to)
|
||||
}
|
||||
func (to timeout) Timeout() {}
|
||||
|
||||
type notImpl string
|
||||
|
||||
func (ni notImpl) Error() string {
|
||||
return string(ni)
|
||||
}
|
||||
func (ni notImpl) NotImplemented() {}
|
||||
|
||||
type internal string
|
||||
|
||||
func (nt internal) Error() string {
|
||||
return string(nt)
|
||||
}
|
||||
func (nt internal) Internal() {}
|
||||
|
||||
type maskInternal string
|
||||
|
||||
func (mnt maskInternal) Error() string {
|
||||
return string(mnt)
|
||||
}
|
||||
func (mnt maskInternal) Internal() {}
|
||||
func (mnt maskInternal) Maskable() {}
|
||||
|
|
99
libnetwork/types/types_test.go
Normal file
99
libnetwork/types/types_test.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
_ "github.com/docker/libnetwork/netutils"
|
||||
)
|
||||
|
||||
func TestErrorConstructors(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = BadRequestErrorf("Io ho %d uccello", 1)
|
||||
if err.Error() != "Io ho 1 uccello" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(BadRequestError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = NotFoundErrorf("Can't find the %s", "keys")
|
||||
if err.Error() != "Can't find the keys" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(NotFoundError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = ForbiddenErrorf("Can't open door %d", 2)
|
||||
if err.Error() != "Can't open door 2" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(ForbiddenError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = NotImplementedErrorf("Functionality %s is not implemented", "x")
|
||||
if err.Error() != "Functionality x is not implemented" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(NotImplementedError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = TimeoutErrorf("Process %s timed out", "abc")
|
||||
if err.Error() != "Process abc timed out" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(TimeoutError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = NoServiceErrorf("Driver %s is not available", "mh")
|
||||
if err.Error() != "Driver mh is not available" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(NoServiceError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = InternalErrorf("Not sure what happened")
|
||||
if err.Error() != "Not sure what happened" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(InternalError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = InternalMaskableErrorf("Minor issue, it can be ignored")
|
||||
if err.Error() != "Minor issue, it can be ignored" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(InternalError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := err.(MaskableError); !ok {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue