1/* 2Copyright 2016 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package net 18 19import ( 20 "fmt" 21 "net" 22 "strings" 23) 24 25// IPNetSet maps string to net.IPNet. 26type IPNetSet map[string]*net.IPNet 27 28// ParseIPNets parses string slice to IPNetSet. 29func ParseIPNets(specs ...string) (IPNetSet, error) { 30 ipnetset := make(IPNetSet) 31 for _, spec := range specs { 32 spec = strings.TrimSpace(spec) 33 _, ipnet, err := net.ParseCIDR(spec) 34 if err != nil { 35 return nil, err 36 } 37 k := ipnet.String() // In case of normalization 38 ipnetset[k] = ipnet 39 } 40 return ipnetset, nil 41} 42 43// Insert adds items to the set. 44func (s IPNetSet) Insert(items ...*net.IPNet) { 45 for _, item := range items { 46 s[item.String()] = item 47 } 48} 49 50// Delete removes all items from the set. 51func (s IPNetSet) Delete(items ...*net.IPNet) { 52 for _, item := range items { 53 delete(s, item.String()) 54 } 55} 56 57// Has returns true if and only if item is contained in the set. 58func (s IPNetSet) Has(item *net.IPNet) bool { 59 _, contained := s[item.String()] 60 return contained 61} 62 63// HasAll returns true if and only if all items are contained in the set. 64func (s IPNetSet) HasAll(items ...*net.IPNet) bool { 65 for _, item := range items { 66 if !s.Has(item) { 67 return false 68 } 69 } 70 return true 71} 72 73// Difference returns a set of objects that are not in s2 74// For example: 75// s1 = {a1, a2, a3} 76// s2 = {a1, a2, a4, a5} 77// s1.Difference(s2) = {a3} 78// s2.Difference(s1) = {a4, a5} 79func (s IPNetSet) Difference(s2 IPNetSet) IPNetSet { 80 result := make(IPNetSet) 81 for k, i := range s { 82 _, found := s2[k] 83 if found { 84 continue 85 } 86 result[k] = i 87 } 88 return result 89} 90 91// StringSlice returns a []string with the String representation of each element in the set. 92// Order is undefined. 93func (s IPNetSet) StringSlice() []string { 94 a := make([]string, 0, len(s)) 95 for k := range s { 96 a = append(a, k) 97 } 98 return a 99} 100 101// IsSuperset returns true if and only if s1 is a superset of s2. 102func (s IPNetSet) IsSuperset(s2 IPNetSet) bool { 103 for k := range s2 { 104 _, found := s[k] 105 if !found { 106 return false 107 } 108 } 109 return true 110} 111 112// Equal returns true if and only if s1 is equal (as a set) to s2. 113// Two sets are equal if their membership is identical. 114// (In practice, this means same elements, order doesn't matter) 115func (s IPNetSet) Equal(s2 IPNetSet) bool { 116 return len(s) == len(s2) && s.IsSuperset(s2) 117} 118 119// Len returns the size of the set. 120func (s IPNetSet) Len() int { 121 return len(s) 122} 123 124// IPSet maps string to net.IP 125type IPSet map[string]net.IP 126 127// ParseIPSet parses string slice to IPSet 128func ParseIPSet(items ...string) (IPSet, error) { 129 ipset := make(IPSet) 130 for _, item := range items { 131 ip := net.ParseIP(strings.TrimSpace(item)) 132 if ip == nil { 133 return nil, fmt.Errorf("error parsing IP %q", item) 134 } 135 136 ipset[ip.String()] = ip 137 } 138 139 return ipset, nil 140} 141 142// Insert adds items to the set. 143func (s IPSet) Insert(items ...net.IP) { 144 for _, item := range items { 145 s[item.String()] = item 146 } 147} 148 149// Delete removes all items from the set. 150func (s IPSet) Delete(items ...net.IP) { 151 for _, item := range items { 152 delete(s, item.String()) 153 } 154} 155 156// Has returns true if and only if item is contained in the set. 157func (s IPSet) Has(item net.IP) bool { 158 _, contained := s[item.String()] 159 return contained 160} 161 162// HasAll returns true if and only if all items are contained in the set. 163func (s IPSet) HasAll(items ...net.IP) bool { 164 for _, item := range items { 165 if !s.Has(item) { 166 return false 167 } 168 } 169 return true 170} 171 172// Difference returns a set of objects that are not in s2 173// For example: 174// s1 = {a1, a2, a3} 175// s2 = {a1, a2, a4, a5} 176// s1.Difference(s2) = {a3} 177// s2.Difference(s1) = {a4, a5} 178func (s IPSet) Difference(s2 IPSet) IPSet { 179 result := make(IPSet) 180 for k, i := range s { 181 _, found := s2[k] 182 if found { 183 continue 184 } 185 result[k] = i 186 } 187 return result 188} 189 190// StringSlice returns a []string with the String representation of each element in the set. 191// Order is undefined. 192func (s IPSet) StringSlice() []string { 193 a := make([]string, 0, len(s)) 194 for k := range s { 195 a = append(a, k) 196 } 197 return a 198} 199 200// IsSuperset returns true if and only if s1 is a superset of s2. 201func (s IPSet) IsSuperset(s2 IPSet) bool { 202 for k := range s2 { 203 _, found := s[k] 204 if !found { 205 return false 206 } 207 } 208 return true 209} 210 211// Equal returns true if and only if s1 is equal (as a set) to s2. 212// Two sets are equal if their membership is identical. 213// (In practice, this means same elements, order doesn't matter) 214func (s IPSet) Equal(s2 IPSet) bool { 215 return len(s) == len(s2) && s.IsSuperset(s2) 216} 217 218// Len returns the size of the set. 219func (s IPSet) Len() int { 220 return len(s) 221} 222