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  }