package pkg import ( "errors" "strconv" "strings" ) type ( RelayAgentSubOptions struct { ID1 string `json:"id1"` ID2 string `json:"id2"` Value1 string `json:"value1"` Value2 string `json:"value2"` } RelayAgentID struct { Add string `json:"add"` Remove string `json:"remove"` Suboptions RelayAgentSubOptions `json:"suboptions"` } DHCPUsername struct { Format string `json:"format"` Separator1 string `json:"separator1"` Separator2 string `json:"separator2"` SuboptionID1 string `json:"suboption_id1"` SuboptionID2 string `json:"suboption_id2"` TCL string `json:"tcl"` } DHCPAuthentication struct { Enabled string `json:"enabled"` Username SubscriberID `json:"username"` Virtual string `json:"virtual"` } SubscriberDiscovery struct { Enable string `json:"enabled"` SubscriberID SubscriberID `json:"subscriber_id"` } SubscriberID struct { Format string `json:"format"` Separator1 string `json:"separator1"` Separator2 string `json:"separator2"` SubOptionID1 string `json:"suboption_id1,omitempty"` SubOptionID2 string `json:"suboption_id2,omitempty"` TCL string `json:"tcl"` } DHCPv4Profile struct { ProfileCommon Authentication DHCPAuthentication `json:"authentication"` DefaultLeaseTime int `json:"default_lease_time"` IdleTimeout int `json:"idle_timeout"` MaxHops int `json:"max_hops"` Mode string `json:"mode"` RelayAgentID RelayAgentID `json:"relay_agent_id"` SubscriberDiscovery SubscriberDiscovery `json:"subscriber_discovery"` TransactionTimeout int `json:"transaction_timeout"` TTLDecValue string `json:"ttl_dec_value"` TTLValue int `json:"ttl_value"` } ) func ParseSubscriberID(raw string) (p SubscriberID) { for _, line := range strings.Split(raw, "\n") { f := strings.Fields(line) if len(f) == 0 { continue // skip empty lines } switch strings.ToLower(f[0]) { case "format": p.Format = strings.Join(f[1:], " ") case "separator1": p.Separator1 = strings.Join(f[1:], " ") case "separator2": p.Separator2 = strings.Join(f[1:], " ") case "suboption-id1": p.SubOptionID1 = strings.Join(f[1:], " ") case "suboption-id2": p.SubOptionID2 = strings.Join(f[1:], " ") case "tcl": p.TCL = strings.Join(f[1:], " ") } } return } func ParseSubscriberDiscovery(raw string) (p SubscriberDiscovery) { inSub := false var sub string for _, line := range strings.Split(raw, "\n") { if inSub { if line == " }" { inSub = false p.SubscriberID = ParseSubscriberID(sub) sub = "" continue } sub = sub + line + "\n" } f := strings.Fields(line) if len(f) == 0 { continue // skip empty lines } switch strings.ToLower(f[0]) { case "enabled": p.Enable = strings.Join(f[1:], " ") case "subscriber-id": inSub = true } } return } func ParseRelayAgentSubOptions(raw string) (p RelayAgentSubOptions) { for _, line := range strings.Split(raw, "\n") { f := strings.Fields(line) if len(f) == 0 { continue // skip empty lines } switch strings.ToLower(f[0]) { case "id1": p.ID1 = strings.Join(f[1:], " ") case "id2": p.ID2 = strings.Join(f[1:], " ") case "value1": p.Value1 = strings.Join(f[1:], " ") case "value2": p.Value2 = strings.Join(f[1:], " ") } } return } func ParseRelayAgentID(raw string) (p RelayAgentID) { inSub := false var sub string for _, line := range strings.Split(raw, "\n") { if inSub { if line == " }" { inSub = false p.Suboptions = ParseRelayAgentSubOptions(sub) sub = "" continue } sub = sub + line + "\n" } f := strings.Fields(line) if len(f) == 0 { continue // skip empty lines } switch strings.ToLower(f[0]) { case "add": p.Add = strings.Join(f[1:], " ") case "remove": p.Remove = strings.Join(f[1:], " ") case "suboptions": inSub = true } } return } func ParseDHCPAuthentication(raw string) (p DHCPAuthentication) { inUser := false var user string for _, line := range strings.Split(raw, "\n") { if inUser { if line == " }" { inUser = false p.Username = ParseSubscriberID(user) user = "" } user = user + line + "\n" } f := strings.Fields(line) if len(f) == 0 { continue // skip empty lines } switch strings.ToLower(f[0]) { case "enabled": p.Enabled = strings.Join(f[1:], " ") case "user-name": inUser = true case "virtual": p.Virtual = strings.Join(f[1:], " ") } } return } func ParseDHCPv4Profile(raw string) (*DHCPv4Profile, error) { p := new(DHCPv4Profile) split := strings.Split(raw, "\n") if !strings.Contains(split[0], "ltm profile dhcpv4") { return nil, errors.New("not a dhcpv4 profile") } p.ProfileCommon = parseCommon(raw) inAuth := false inRelayAgentID := false inSubDisc := false // For holding sub-portions to pass to sub-parsers var auth string var relay string var sub string for _, line := range split { if inAuth { if line == " }" { inAuth = false p.Authentication = ParseDHCPAuthentication(auth) auth = "" continue } auth = auth + line + "\n" } if inSubDisc { if line == " }" { inSubDisc = false p.SubscriberDiscovery = ParseSubscriberDiscovery(sub) sub = "" continue } sub = sub + line + "\n" } if inRelayAgentID { if line == " }" { inRelayAgentID = false p.RelayAgentID = ParseRelayAgentID(relay) relay = "" continue } relay = relay + line + "\n" } f := strings.Fields(line) switch strings.ToLower(f[0]) { case "authentication": inAuth = true case "subscriber-discovery": inSubDisc = true case "relay-agent-id": inRelayAgentID = true case "default-lease-time": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.DefaultLeaseTime = i case "idle-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.IdleTimeout = i case "max-hops": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.MaxHops = i case "mode": p.Mode = strings.Join(f[1:], " ") case "transaction-timeout": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.TransactionTimeout = i case "ttl-dec-value": p.TTLDecValue = strings.Join(f[1:], " ") case "ttl-value": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return nil, err } p.TTLValue = i } } return p, nil }