github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/util/net/port_range.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package net 18 19 import ( 20 "fmt" 21 "strconv" 22 "strings" 23 ) 24 25 // PortRange represents a range of TCP/UDP ports. To represent a single port, 26 // set Size to 1. 27 type PortRange struct { 28 Base int 29 Size int 30 } 31 32 // Contains tests whether a given port falls within the PortRange. 33 func (pr *PortRange) Contains(p int) bool { 34 return (p >= pr.Base) && ((p - pr.Base) < pr.Size) 35 } 36 37 // String converts the PortRange to a string representation, which can be 38 // parsed by PortRange.Set or ParsePortRange. 39 func (pr PortRange) String() string { 40 if pr.Size == 0 { 41 return "" 42 } 43 return fmt.Sprintf("%d-%d", pr.Base, pr.Base+pr.Size-1) 44 } 45 46 // Set parses a string of the form "value", "min-max", or "min+offset", inclusive at both ends, and 47 // sets the PortRange from it. This is part of the flag.Value and pflag.Value 48 // interfaces. 49 func (pr *PortRange) Set(value string) error { 50 const ( 51 SinglePortNotation = 1 << iota 52 HyphenNotation 53 PlusNotation 54 ) 55 56 value = strings.TrimSpace(value) 57 hyphenIndex := strings.Index(value, "-") 58 plusIndex := strings.Index(value, "+") 59 60 if value == "" { 61 pr.Base = 0 62 pr.Size = 0 63 return nil 64 } 65 66 var err error 67 var low, high int 68 var notation int 69 70 if plusIndex == -1 && hyphenIndex == -1 { 71 notation |= SinglePortNotation 72 } 73 if hyphenIndex != -1 { 74 notation |= HyphenNotation 75 } 76 if plusIndex != -1 { 77 notation |= PlusNotation 78 } 79 80 switch notation { 81 case SinglePortNotation: 82 var port int 83 port, err = strconv.Atoi(value) 84 if err != nil { 85 return err 86 } 87 low = port 88 high = port 89 case HyphenNotation: 90 low, err = strconv.Atoi(value[:hyphenIndex]) 91 if err != nil { 92 return err 93 } 94 high, err = strconv.Atoi(value[hyphenIndex+1:]) 95 if err != nil { 96 return err 97 } 98 case PlusNotation: 99 var offset int 100 low, err = strconv.Atoi(value[:plusIndex]) 101 if err != nil { 102 return err 103 } 104 offset, err = strconv.Atoi(value[plusIndex+1:]) 105 if err != nil { 106 return err 107 } 108 high = low + offset 109 default: 110 return fmt.Errorf("unable to parse port range: %s", value) 111 } 112 113 if low > 65535 || high > 65535 { 114 return fmt.Errorf("the port range cannot be greater than 65535: %s", value) 115 } 116 117 if high < low { 118 return fmt.Errorf("end port cannot be less than start port: %s", value) 119 } 120 121 pr.Base = low 122 pr.Size = 1 + high - low 123 return nil 124 } 125 126 // Type returns a descriptive string about this type. This is part of the 127 // pflag.Value interface. 128 func (*PortRange) Type() string { 129 return "portRange" 130 } 131 132 // ParsePortRange parses a string of the form "min-max", inclusive at both 133 // ends, and initializes a new PortRange from it. 134 func ParsePortRange(value string) (*PortRange, error) { 135 pr := &PortRange{} 136 err := pr.Set(value) 137 if err != nil { 138 return nil, err 139 } 140 return pr, nil 141 } 142 143 func ParsePortRangeOrDie(value string) *PortRange { 144 pr, err := ParsePortRange(value) 145 if err != nil { 146 panic(fmt.Sprintf("couldn't parse port range %q: %v", value, err)) 147 } 148 return pr 149 }