diff --git a/core/pkg/ingress/annotations/ipwhitelist/main.go b/core/pkg/ingress/annotations/ipwhitelist/main.go index 91df4bf60..e775abe3a 100644 --- a/core/pkg/ingress/annotations/ipwhitelist/main.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/errors" extensions "k8s.io/api/extensions/v1beta1" - "k8s.io/kubernetes/pkg/util/net/sets" + "k8s.io/ingress/core/pkg/net" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ing_errors "k8s.io/ingress/core/pkg/ingress/errors" @@ -92,8 +92,8 @@ func (a ipwhitelist) Parse(ing *extensions.Ingress) (interface{}, error) { } values := strings.Split(val, ",") - ipnets, err := sets.ParseIPNets(values...) - if err != nil { + ipnets, ips, err := net.ParseIPNets(values...) + if err != nil && len(ips) == 0 { return &SourceRange{CIDR: defBackend.WhitelistSourceRange}, ing_errors.LocationDenied{ Reason: errors.Wrap(err, "the annotation does not contain a valid IP address or network"), } @@ -103,6 +103,9 @@ func (a ipwhitelist) Parse(ing *extensions.Ingress) (interface{}, error) { for k := range ipnets { cidrs = append(cidrs, k) } + for k := range ips { + cidrs = append(cidrs, k) + } sort.Strings(cidrs) diff --git a/core/pkg/net/ipnet.go b/core/pkg/net/ipnet.go new file mode 100644 index 000000000..b48d13db8 --- /dev/null +++ b/core/pkg/net/ipnet.go @@ -0,0 +1,53 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package net + +import ( + "net" + "strings" +) + +// IPNet maps string to net.IPNet. +type IPNet map[string]*net.IPNet + +// IP maps string to net.IP. +type IP map[string]net.IP + +// ParseIPNets parses string slice to IPNet. +func ParseIPNets(specs ...string) (IPNet, IP, error) { + ipnetset := make(IPNet) + ipset := make(IP) + + for _, spec := range specs { + spec = strings.TrimSpace(spec) + _, ipnet, err := net.ParseCIDR(spec) + if err != nil { + ip := net.ParseIP(spec) + if ip == nil { + return nil, nil, err + } + i := ip.String() + ipset[i] = ip + continue + } + + k := ipnet.String() + ipnetset[k] = ipnet + } + + return ipnetset, ipset, nil +} diff --git a/core/pkg/net/ipnet_test.go b/core/pkg/net/ipnet_test.go new file mode 100644 index 000000000..3ce1345c6 --- /dev/null +++ b/core/pkg/net/ipnet_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package net + +import ( + "testing" +) + +func TestNewIPSet(t *testing.T) { + ipsets, ips, err := ParseIPNets("1.0.0.0", "2.0.0.0/8", "3.0.0.0/8") + if err != nil { + t.Errorf("error parsing IPNets: %v", err) + } + if len(ipsets) != 2 { + t.Errorf("Expected len=2: %d", len(ipsets)) + } + if len(ips) != 1 { + t.Errorf("Expected len=1: %d", len(ips)) + } +}