// 2020 Rackspace, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package netparse import ( "regexp" "strconv" "strings" ) var ( ipAclRE = regexp.MustCompile(`(?i)(i|)(p|pv6)\s+access-list\s+(\S+)\n((.|\n)*?)(\n\S|$)`) ipExtAclRE = regexp.MustCompile(`(?i)(i|)(p|pv6)\s+access-list\s+extended\s+(\S+)\n((.|\n)*?)(\n\S|$)`) lineAclRE = regexp.MustCompile(`(?i)([0-9]+)\s+(.*?)$`) ) type ( // ACL struct describes the parsed items within a access-list ACL struct { Name string `json:"name"` IPV6 bool `json:"ipv6"` Extended bool `json:"extended"` Rules []ACLRule `json:"rules"` } // ACLRule struct describes the parsed items within a single // access-list entry ACLRule struct { Line int `json:"line"` Rule string `json:"rule"` } ) // ACLParse is the parsing method for the ACL struct. This func ACLParse(s string) []ACL { retVal := make([]ACL, 0) for _, acl := range ipAclRE.FindAllStringSubmatch(s, -1) { retVal = append(retVal, ACL{ Name: acl[3], IPV6: isV6(acl[2]), Rules: parseACL(acl[4]), }) } for _, acl := range ipExtAclRE.FindAllStringSubmatch(s, -1) { retVal = append(retVal, ACL{ Name: acl[3], IPV6: isV6(acl[2]), Extended: true, Rules: parseACL(acl[4]), }) } return retVal } func isV6(s string) bool { return s == "pv6" } func parseACL(s string) []ACLRule { retVal := make([]ACLRule, 0) for i, r := range strings.Split(s, "\n") { r = strings.TrimSpace(r) if r == "" { continue } m := lineAclRE.FindStringSubmatch(r) if len(m) == 0 { retVal = append(retVal, ACLRule{Line: i + 1, Rule: r}) continue } retVal = append(retVal, ACLRule{ Line: func() int { if n, err := strconv.Atoi(m[1]); err == nil { return n } return 0 }(), Rule: m[2], }) } return retVal }