package pkg import ( "github.rackspace.com/gorax/tools/util" "regexp" "strings" ) type ( Rule struct { Description string `json:"description,omitempty"` Name *string `json:"name"` Action *string `json:"action"` IpProto *string `json:"ip-protocol,omitempty"` Dest *TrafficTypes `json:"destination,omitempty"` Source *TrafficTypes `json:"source,omitempty"` Irule *string `json:"irule,omitempty"` RuleList *string `json:"rule-list,omitempty"` Icmp []*Icmp `json:"icmp,omitempty"` } TrafficTypes struct { Ports []*RulePort `json:"ports,omitempty"` PortList []*string `json:"port-lists,omitempty"` AddrList []*string `json:"address-lists,omitempty"` Address []*RuleAddress `json:"addresses,omitempty"` Vlans []*string `json:"vlans,omitempty"` } Icmp struct { IcmpType *int `json:"type"` Prop *string `json:"properties,omitempty"` } RuleAddress struct { Address *string `json:"address"` Prop *string `json:"properties,omitempty"` } RulePort struct { Port *string `json:"port"` Prop *string `json:"properties,omitempty"` } ) func (r *Rule) parse(s string) { for _, v := range regexp.MustCompile(`(\S+)\s+{((.|\n)*?)$`).FindAllStringSubmatch(s, -1) { b := braceParse(v[2]) for _, v1 := range b { if strings.Contains(v1, "destination") { r.Dest = r.hosts(`(?i)destination\s+{((.|\n)*?)$`, v1) } if strings.Contains(v1, "source") { r.Source = r.hosts(`(?i)source\s+{((.|\n)*?)$`, v1) } if strings.Contains(v1, "icmp") { r.icmpList(v1) } } r.Name = &v[1] r.Description = util.RegexpFindString(regexp.MustCompile(`(?i)description "(.*)"`), v[2]) Action := util.RegexpFindString(regexp.MustCompile(`action\s+(\S+)`), v[2]) IpProto := util.RegexpFindString(regexp.MustCompile(`ip-protocol\s+(\S+)`), v[2]) Irule := util.RegexpFindString(regexp.MustCompile(`irule\s+(\S+)`), v[2]) RuleList := util.RegexpFindString(regexp.MustCompile(`rule-list\s+(\S+)`), v[2]) r.Action = &Action r.IpProto = &IpProto r.Irule = &Irule r.RuleList = &RuleList } } func (r *Rule) hosts(re string, s string) *TrafficTypes { var d TrafficTypes t := regexp.MustCompile(re).FindStringSubmatch(s) if len(t) > 0 { for _, v1 := range braceParse(t[1]) { if strings.Contains(v1, "address-lists") { d.addrLists(v1) } else if strings.Contains(v1, "port-lists") { d.portLists(v1) } else if strings.Contains(v1, "addresses") { d.addrList(v1) } else if strings.Contains(v1, "ports") { d.portList(v1) } else if strings.Contains(v1, "vlans") { d.vlanList(v1) } } return &d } return nil } func (r *Rule) icmpList(s string) { ri := regexp.MustCompile(`(?i)icmp\s+{((.|\n)*?)$`).FindStringSubmatch(s) if len(ri) > 0 { for _, v := range regexp.MustCompile(`(\d+)\s+{((.|\n)*?)}`).FindAllStringSubmatch(ri[1], -1) { r.Icmp = append(r.Icmp, &Icmp{ IcmpType: atoi(v[1]), Prop: nil, }) } } } func (t *TrafficTypes) addrList(s string) { r := regexp.MustCompile(`(?i)addresses\s+{((.|\n)*?)$`).FindStringSubmatch(s) if len(r) > 0 { for _, v := range regexp.MustCompile(`(\S+)\s+{((.|\n)*?)}`).FindAllStringSubmatch(r[1], -1) { t.Address = append(t.Address, &RuleAddress{ Address: &v[1], Prop: nil, }) } } } func (t *TrafficTypes) addrLists(s string) { r := regexp.MustCompile(`address-lists\s+{((.|\n)*?)}`).FindStringSubmatch(s) if len(r) > 0 { for _, v := range regexp.MustCompile(`(\S+)`).FindAllStringSubmatch(r[1], -1) { t.AddrList = append(t.AddrList, &v[1]) } } } func (t *TrafficTypes) portList(s string) { r := regexp.MustCompile(`ports\s+{((.|\n)*?)$`).FindStringSubmatch(s) if len(r) > 0 { for _, v := range regexp.MustCompile(`(\S+)\s+{((.|\n)*?)}`).FindAllStringSubmatch(r[1], -1) { t.Ports = append(t.Ports, &RulePort{ Port: &v[1], Prop: nil, }) } } } func (t *TrafficTypes) portLists(s string) { r := regexp.MustCompile(`port-lists\s+{((.|\n)*?)}`).FindStringSubmatch(s) if r != nil { for _, v := range regexp.MustCompile(`(\S+)`).FindAllStringSubmatch(r[1], -1) { t.PortList = append(t.PortList, &v[1]) } } } func (t *TrafficTypes) vlanList(s string) { r := regexp.MustCompile(`vlans\s+{((.|\n)*?)}`).FindStringSubmatch(s) if len(r) > 0 { for _, v := range regexp.MustCompile(`(\S+)`).FindAllStringSubmatch(r[1], -1) { t.Vlans = append(t.Vlans, &v[1]) } } }