Files
restitux 05c3b0ff0b
Build and Test / build-test-publish-coverage (push) Failing after 1m36s
added support for views
2025-02-13 21:28:47 -07:00

112 lines
2.1 KiB
Go

package netbox
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type APIRequestClient struct {
Client *http.Client
NetboxURL *url.URL
Token string
UserAgent string
}
type APIResultModel interface {
Record | Zone | View
}
type APIManyResponse[T APIResultModel] struct {
Count int `json:"count"`
Next string `json:"next"`
Previous string `json:"previous"`
Results []T `json:"results"`
}
func doGet(
requestClient *APIRequestClient,
url string,
) (*http.Response, error) {
request, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
request.Header.Set(
"Authorization",
fmt.Sprintf("Token %s", requestClient.Token),
)
request.Header.Set("User-Agent", requestClient.UserAgent)
return requestClient.Client.Do(request)
}
func responseError(response *http.Response) error {
if response.StatusCode != http.StatusOK {
return fmt.Errorf(
"request error [%d] %q",
response.StatusCode,
response.Status,
)
}
return nil
}
func get[T APIResultModel](
requestClient *APIRequestClient,
url string,
) (T, error) {
var out T
response, err := doGet(requestClient, url)
if err != nil {
return out, err
}
defer response.Body.Close()
if err := responseError(response); err != nil {
return out, err
}
decoder := json.NewDecoder(response.Body)
if err := decoder.Decode(&out); err != nil {
return out, fmt.Errorf("could not unmarshal response: %w", err)
}
return out, nil
}
func getMany[T APIResultModel](
requestClient *APIRequestClient,
url string,
) ([]T, error) {
nextUrl := url
var out []T
for nextUrl != "" {
response, err := doGet(requestClient, nextUrl)
if err != nil {
return out, err
}
defer response.Body.Close()
if err := responseError(response); err != nil {
return out, err
}
var apiResponse APIManyResponse[T]
decoder := json.NewDecoder(response.Body)
if err := decoder.Decode(&apiResponse); err != nil {
return out, fmt.Errorf("could not unmarshal response: %w", err)
}
if out == nil {
out = make([]T, 0, apiResponse.Count)
}
out = append(out, apiResponse.Results...)
nextUrl = apiResponse.Next
}
return out, nil
}