package pkg import ( "errors" "strconv" "strings" ) type ( RemoteIDOption struct { Add bool `json:"add"` EnterpriseNumber int `json:"enterprise_number"` Remove bool `json:"remove"` Value string `json:"value"` } SubscriberIDOption struct { Add bool `json:"add"` Remove bool `json:"remove"` Value string `json:"value"` } DHCPv6Profile struct { ProfileCommon Authentication DHCPAuthentication `json:"authentication"` DefaultLeaseTime int `json:"default_lease_time"` IdleTimeout int `json:"idle_timeout"` Mode string `json:"mode"` RemoteIDOption RemoteIDOption `json:"remote_id_option"` SubscriberDiscovery SubscriberDiscovery `json:"subscriber_discovery"` SubscriberIDOption SubscriberIDOption `json:"subscriber_id_option"` TransactionTimeout int `json:"transaction_timeout"` } ) func ParseRemoteIDOption(raw string) (RemoteIDOption, error) { var p RemoteIDOption for _, line := range strings.Split(raw, "\n") { f := strings.Fields(line) if len(f) == 0 { continue } switch strings.ToLower(f[0]) { case "add": p.Add = parseBool(f[1]) case "enterprise-number": i, err := strconv.Atoi(f[1]) if err != nil { log.WithField("data", f[1]).Error(err.Error()) return p, err } p.EnterpriseNumber = i case "remove": p.Remove = parseBool(f[1]) case "value": p.Value = strings.Join(f[1:], " ") } } return p, nil } func ParseSubscriberIDOption(raw string) (p SubscriberIDOption) { for _, line := range strings.Split(raw, "\n") { f := strings.Fields(line) if len(f) == 0 { continue } switch strings.ToLower(f[0]) { case "add": p.Add = parseBool(f[1]) case "remove": p.Remove = parseBool(f[1]) case "value": p.Value = strings.Join(f[1:], " ") } } return } func ParseDHCPv6Profile(raw string) (*DHCPv6Profile, error) { p := new(DHCPv6Profile) split := strings.Split(raw, "\n") if !strings.Contains(split[0], "ltm profile dhcpv6") { return nil, errors.New("not a dhcpv6 profile") } p.ProfileCommon = parseCommon(raw) // tracks if we're in subsections var inAuth, inSubDisc, inRemote, inSubID bool // stores the subsection to pass it to the subparser var auth, remote, subd, subi string for _, line := range split { if inAuth { if line == " }" { inAuth = false p.Authentication = ParseDHCPAuthentication(auth) auth = "" continue } auth = auth + line + "\n" } if inRemote { if line == " }" { inRemote = false i, err := ParseRemoteIDOption(remote) if err != nil { return nil, err } p.RemoteIDOption = i remote = "" continue } remote = remote + line + "\n" } if inSubDisc { if line == " }" { inSubDisc = false p.SubscriberDiscovery = ParseSubscriberDiscovery(subd) subd = "" continue } subd = subd + line + "\n" } if inSubID { if line == " }" { inSubID = false p.SubscriberIDOption = ParseSubscriberIDOption(subi) subi = "" continue } subi = subi + line + "\n" } f := strings.Fields(line) switch strings.ToLower(f[0]) { case "authentication": inAuth = 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 "mode": p.Mode = strings.Join(f[1:], " ") case "remote-id-option": inRemote = true case "subscriber-discovery": inSubDisc = true case "subscriber-id-option": inSubID = true 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 } } return p, nil }