diff --git a/pkg/registry/core/service/ipallocator/allocator.go b/pkg/registry/core/service/ipallocator/allocator.go index fe25a30212c..dd206eb1d00 100644 --- a/pkg/registry/core/service/ipallocator/allocator.go +++ b/pkg/registry/core/service/ipallocator/allocator.go @@ -40,11 +40,18 @@ type Interface interface { var ( ErrFull = errors.New("range is full") - ErrNotInRange = errors.New("provided IP is not in the valid range") ErrAllocated = errors.New("provided IP is already allocated") ErrMismatchedNetwork = errors.New("the provided network does not match the current range") ) +type ErrNotInRange struct { + ValidRange string +} + +func (e *ErrNotInRange) Error() string { + return fmt.Sprintf("provided IP is not in the valid range. The range of valid IPs is %s", e.ValidRange) +} + // Range is a contiguous block of IPs that can be allocated atomically. // // The internal structure of the range is: @@ -135,7 +142,7 @@ func (r *Range) CIDR() net.IPNet { func (r *Range) Allocate(ip net.IP) error { ok, offset := r.contains(ip) if !ok { - return ErrNotInRange + return &ErrNotInRange{r.net.String()} } allocated, err := r.alloc.Allocate(offset) diff --git a/pkg/registry/core/service/ipallocator/allocator_test.go b/pkg/registry/core/service/ipallocator/allocator_test.go index 1b6156feb91..ff854ce31b9 100644 --- a/pkg/registry/core/service/ipallocator/allocator_test.go +++ b/pkg/registry/core/service/ipallocator/allocator_test.go @@ -78,16 +78,19 @@ func TestAllocate(t *testing.T) { if err := r.Release(released); err != nil { t.Fatal(err) } - if err := r.Allocate(net.ParseIP("192.168.0.1")); err != ErrNotInRange { + err = r.Allocate(net.ParseIP("192.168.0.1")) + if _, ok := err.(*ErrNotInRange); !ok { t.Fatal(err) } if err := r.Allocate(net.ParseIP("192.168.1.1")); err != ErrAllocated { t.Fatal(err) } - if err := r.Allocate(net.ParseIP("192.168.1.0")); err != ErrNotInRange { + err = r.Allocate(net.ParseIP("192.168.1.0")) + if _, ok := err.(*ErrNotInRange); !ok { t.Fatal(err) } - if err := r.Allocate(net.ParseIP("192.168.1.255")); err != ErrNotInRange { + err = r.Allocate(net.ParseIP("192.168.1.255")) + if _, ok := err.(*ErrNotInRange); !ok { t.Fatal(err) } if f := r.Free(); f != 1 { diff --git a/pkg/registry/core/service/ipallocator/controller/repair.go b/pkg/registry/core/service/ipallocator/controller/repair.go index df46a871285..7e13115f1f0 100644 --- a/pkg/registry/core/service/ipallocator/controller/repair.go +++ b/pkg/registry/core/service/ipallocator/controller/repair.go @@ -154,7 +154,7 @@ func (c *Repair) runOnce() error { // TODO: send event // cluster IP is duplicate runtime.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s was assigned to multiple services; please recreate", ip, svc.Name, svc.Namespace)) - case ipallocator.ErrNotInRange: + case err.(*ipallocator.ErrNotInRange): // TODO: send event // cluster IP is out of range runtime.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s is not within the service CIDR %s; please recreate", ip, svc.Name, svc.Namespace, c.network)) diff --git a/pkg/registry/core/service/ipallocator/storage/storage_test.go b/pkg/registry/core/service/ipallocator/storage/storage_test.go index efb1dfa6e01..cd4e34c3230 100644 --- a/pkg/registry/core/service/ipallocator/storage/storage_test.go +++ b/pkg/registry/core/service/ipallocator/storage/storage_test.go @@ -78,7 +78,8 @@ func TestEmpty(t *testing.T) { func TestErrors(t *testing.T) { _, storage, _, _, destroyFunc := newStorage(t) defer destroyFunc() - if err := storage.Allocate(net.ParseIP("192.168.0.0")); err != ipallocator.ErrNotInRange { + err := storage.Allocate(net.ParseIP("192.168.0.0")) + if _, ok := err.(*ipallocator.ErrNotInRange); !ok { t.Fatal(err) } }