package opnsense import ( "fmt" "strconv" ) type unboundDNSStatusResponse struct { Status string `json:"status"` Data struct { Total struct { Num struct { Queries string `json:"queries"` QueriesIPRatelimited string `json:"queries_ip_ratelimited"` QueriesCookieValid string `json:"queries_cookie_valid"` QueriesCookieClient string `json:"queries_cookie_client"` QueriesCookieInvalid string `json:"queries_cookie_invalid"` Cachehits string `json:"cachehits"` Cachemiss string `json:"cachemiss"` Prefetch string `json:"prefetch"` QueriesTimedOut string `json:"queries_timed_out"` Expired string `json:"expired"` Recursivereplies string `json:"recursivereplies"` Dnscrypt struct { Crypted string `json:"crypted"` Cert string `json:"cert"` Cleartext string `json:"cleartext"` Malformed string `json:"malformed"` } `json:"dnscrypt"` } `json:"num"` Query struct { QueueTimeUs struct { Max string `json:"max"` } `json:"queue_time_us"` } `json:"query"` Requestlist struct { Avg string `json:"avg"` Max string `json:"max"` Overwritten string `json:"overwritten"` Exceeded string `json:"exceeded"` Current struct { All string `json:"all"` User string `json:"user"` } `json:"current"` } `json:"requestlist"` Recursion struct { Time struct { Avg string `json:"avg"` Median string `json:"median"` } `json:"time"` } `json:"recursion"` Tcpusage string `json:"tcpusage"` } `json:"total"` Time struct { Now string `json:"now"` Up string `json:"up"` Elapsed string `json:"elapsed"` } `json:"time"` Mem struct { Cache struct { Rrset string `json:"rrset"` Message string `json:"message"` DnscryptSharedSecret string `json:"dnscrypt_shared_secret"` DnscryptNonce string `json:"dnscrypt_nonce"` } `json:"cache"` Mod struct { Iterator string `json:"iterator"` Validator string `json:"validator"` Respip string `json:"respip"` Dynlibmod string `json:"dynlibmod"` } `json:"mod"` Streamwait string `json:"streamwait"` HTTP struct { QueryBuffer string `json:"query_buffer"` ResponseBuffer string `json:"response_buffer"` } `json:"http"` } `json:"mem"` Num struct { Query struct { Type struct { A string `json:"A"` Soa string `json:"SOA"` Ptr string `json:"PTR"` Mx string `json:"MX"` Txt string `json:"TXT"` Aaaa string `json:"AAAA"` Srv string `json:"SRV"` Svcb string `json:"SVCB"` HTTPS string `json:"HTTPS"` } `json:"type"` Class struct { In string `json:"IN"` } `json:"class"` Opcode struct { Query string `json:"QUERY"` } `json:"opcode"` TCP string `json:"tcp"` Tcpout string `json:"tcpout"` Udpout string `json:"udpout"` TLS struct { Value string `json:"__value__"` Resume string `json:"resume"` } `json:"tls"` Ipv6 string `json:"ipv6"` HTTPS string `json:"https"` Flags struct { Qr string `json:"QR"` Aa string `json:"AA"` Tc string `json:"TC"` Rd string `json:"RD"` Ra string `json:"RA"` Z string `json:"Z"` Ad string `json:"AD"` Cd string `json:"CD"` } `json:"flags"` Edns struct { Present string `json:"present"` Do string `json:"DO"` } `json:"edns"` Ratelimited string `json:"ratelimited"` Aggressive struct { Noerror string `json:"NOERROR"` Nxdomain string `json:"NXDOMAIN"` } `json:"aggressive"` Dnscrypt struct { SharedSecret struct { Cachemiss string `json:"cachemiss"` } `json:"shared_secret"` Replay string `json:"replay"` } `json:"dnscrypt"` Authzone struct { Up string `json:"up"` Down string `json:"down"` } `json:"authzone"` } `json:"query"` Answer struct { Rcode struct { Noerror string `json:"NOERROR"` Formerr string `json:"FORMERR"` Servfail string `json:"SERVFAIL"` Nxdomain string `json:"NXDOMAIN"` Notimpl string `json:"NOTIMPL"` Refused string `json:"REFUSED"` Nodata string `json:"nodata"` } `json:"rcode"` Secure string `json:"secure"` Bogus string `json:"bogus"` } `json:"answer"` Rrset struct { Bogus string `json:"bogus"` } `json:"rrset"` } `json:"num"` Unwanted struct { Queries string `json:"queries"` Replies string `json:"replies"` } `json:"unwanted"` Msg struct { Cache struct { Count string `json:"count"` MaxCollisions string `json:"max_collisions"` } `json:"cache"` } `json:"msg"` Rrset struct { Cache struct { Count string `json:"count"` MaxCollisions string `json:"max_collisions"` } `json:"cache"` } `json:"rrset"` Infra struct { Cache struct { Count string `json:"count"` } `json:"cache"` } `json:"infra"` Key struct { Cache struct { Count string `json:"count"` } `json:"cache"` } `json:"key"` DnscryptSharedSecret struct { Cache struct { Count string `json:"count"` } `json:"cache"` } `json:"dnscrypt_shared_secret"` DnscryptNonce struct { Cache struct { Count string `json:"count"` } `json:"cache"` } `json:"dnscrypt_nonce"` } `json:"data"` } type UnboundDNSOverview struct { Total int BlocklistSize int Passed int UptimeSeconds float64 AnswerRcodes map[string]int AnswerRcodesTotal int AnnswerBogusTotal int AnswerSecureTotal int QueryTypes map[string]int } func (c *Client) FetchUnboundOverview() (UnboundDNSOverview, *APICallError) { var ( response unboundDNSStatusResponse data UnboundDNSOverview err error errConvertion *APICallError ) url, ok := c.endpoints["unboundDNSStatus"] if !ok { return data, &APICallError{ Endpoint: "unboundDNSStatus", Message: "endpoint not found in client endpoints", StatusCode: 0, } } if err := c.do("GET", url, nil, &response); err != nil { return data, err } data.QueryTypes = make(map[string]int) data.AnswerRcodes = make(map[string]int) data.UptimeSeconds, err = strconv.ParseFloat(response.Data.Time.Up, 64) if err != nil { return data, &APICallError{ Endpoint: string(url), Message: fmt.Sprintf("unable to parse uptime %s", err), StatusCode: 0, } } data.AnnswerBogusTotal, errConvertion = parseStringToInt(response.Data.Num.Answer.Bogus, url) if err != nil { return data, errConvertion } data.AnswerSecureTotal, errConvertion = parseStringToInt(response.Data.Num.Answer.Secure, url) if err != nil { return data, errConvertion } return data, nil }