bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/host/name.go (about) 1 package host 2 3 import ( 4 "errors" 5 "fmt" 6 "net" 7 "strings" 8 9 "bosun.org/name" 10 ) 11 12 const hostRegexPattern = `^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$` 13 14 type hostNameFormatConfig struct { 15 useFullName bool 16 validators []name.Validator 17 } 18 19 // NewHostNameProcessor constructs a new name.Processor for host names 20 func NewHostNameProcessor(useFullName bool) (name.Processor, error) { 21 lenValidator := name.NewLengthValidator(1, 255) 22 regexValidator, err := name.NewRegexpValidator(hostRegexPattern) 23 if err != nil { 24 return nil, err 25 } 26 27 result := &hostNameFormatConfig{ 28 useFullName: useFullName, 29 validators: []name.Validator{lenValidator, regexValidator}, 30 } 31 32 return result, nil 33 } 34 35 // IsValid returns true if the provided name is valid according to https://tools.ietf.org/html/rfc1123 36 func (c *hostNameFormatConfig) IsValid(name string) bool { 37 for _, validator := range c.validators { 38 if !validator.IsValid(name) { 39 return false 40 } 41 } 42 43 return true 44 } 45 46 // FormatName takes a host name and formats it. 47 // 48 // If the name is an IP address then it's simply returned. 49 // 50 // If `useFullName == false` then the name is truncated at the first '.'. If there is no '.' then the full name is 51 // returned. 52 // 53 // The resulting names will always be in lowercase format. 54 func (c *hostNameFormatConfig) FormatName(name string) (string, error) { 55 if !c.useFullName { 56 //only split if string is not an IP address 57 ip := net.ParseIP(name) 58 if ip == nil { 59 name = strings.SplitN(name, ".", 2)[0] 60 } 61 } 62 63 if !c.IsValid(name) { 64 return "", errors.New(fmt.Sprintf("Invalid name of '%s'", name)) 65 } 66 return strings.ToLower(name), nil 67 }