github.com/elfadel/cilium@v1.6.12/pkg/fqdn/matchpattern/matchpattern.go (about) 1 // Copyright 2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package matchpattern 16 17 import ( 18 "errors" 19 "regexp" 20 "strings" 21 22 "github.com/miekg/dns" 23 ) 24 25 const allowedDNSCharsREGroup = "[-a-zA-Z0-9_]" 26 27 // Validate ensures that pattern is a parseable matchPattern. It returns the 28 // regexp generated when validating. 29 func Validate(pattern string) (matcher *regexp.Regexp, err error) { 30 pattern = strings.TrimSpace(pattern) 31 pattern = strings.ToLower(pattern) 32 33 // error check 34 if strings.ContainsAny(pattern, "[]+{},") { 35 return nil, errors.New(`Only alphanumeric ASCII characters, the hyphen "-", "." and "*" are allowed in a matchPattern`) 36 } 37 38 return regexp.Compile(ToRegexp(pattern)) 39 } 40 41 // Sanitize canonicalized the pattern for use by ToRegexp 42 func Sanitize(pattern string) string { 43 if pattern == "*" { 44 return pattern 45 } 46 47 return strings.ToLower(dns.Fqdn(pattern)) 48 } 49 50 // ToRegexp converts a MatchPattern field into a regexp string. It does not 51 // validate the pattern. 52 // It supports: 53 // * to select 0 or more DNS valid characters 54 func ToRegexp(pattern string) string { 55 pattern = strings.TrimSpace(pattern) 56 pattern = strings.ToLower(pattern) 57 58 // handle the * match-all case. This will filter down to the end. 59 if pattern == "*" { 60 return "(^(" + allowedDNSCharsREGroup + "+[.])+$)|(^[.]$)" 61 } 62 63 // base case. * becomes .*, but only for DNS valid characters 64 // NOTE: this only works because the case above does not leave the * 65 pattern = strings.Replace(pattern, "*", allowedDNSCharsREGroup+"*", -1) 66 67 // base case. "." becomes a literal . 68 pattern = strings.Replace(pattern, ".", "[.]", -1) 69 70 // Anchor the match to require the whole string to match this expression 71 return "^" + pattern + "$" 72 }