mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:24:18 -04:00
268 lines
7.0 KiB
Go
268 lines
7.0 KiB
Go
package rest
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/netbirdio/netbird/shared/management/http/util"
|
|
)
|
|
|
|
// APIError represents an error response from the management API.
|
|
type APIError struct {
|
|
StatusCode int
|
|
Message string
|
|
}
|
|
|
|
// Error implements the error interface.
|
|
func (e *APIError) Error() string {
|
|
return e.Message
|
|
}
|
|
|
|
// IsNotFound returns true if the error represents a 404 Not Found response.
|
|
func IsNotFound(err error) bool {
|
|
var apiErr *APIError
|
|
if ok := errors.As(err, &apiErr); ok {
|
|
return apiErr.StatusCode == http.StatusNotFound
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Client Management service HTTP REST API Client
|
|
type Client struct {
|
|
managementURL string
|
|
authHeader string
|
|
httpClient HttpClient
|
|
userAgent string
|
|
|
|
// Accounts NetBird account APIs
|
|
// see more: https://docs.netbird.io/api/resources/accounts
|
|
Accounts *AccountsAPI
|
|
|
|
// Users NetBird users APIs
|
|
// see more: https://docs.netbird.io/api/resources/users
|
|
Users *UsersAPI
|
|
|
|
// Tokens NetBird tokens APIs
|
|
// see more: https://docs.netbird.io/api/resources/tokens
|
|
Tokens *TokensAPI
|
|
|
|
// Peers NetBird peers APIs
|
|
// see more: https://docs.netbird.io/api/resources/peers
|
|
Peers *PeersAPI
|
|
|
|
// SetupKeys NetBird setup keys APIs
|
|
// see more: https://docs.netbird.io/api/resources/setup-keys
|
|
SetupKeys *SetupKeysAPI
|
|
|
|
// Groups NetBird groups APIs
|
|
// see more: https://docs.netbird.io/api/resources/groups
|
|
Groups *GroupsAPI
|
|
|
|
// Policies NetBird policies APIs
|
|
// see more: https://docs.netbird.io/api/resources/policies
|
|
Policies *PoliciesAPI
|
|
|
|
// PostureChecks NetBird posture checks APIs
|
|
// see more: https://docs.netbird.io/api/resources/posture-checks
|
|
PostureChecks *PostureChecksAPI
|
|
|
|
// Networks NetBird networks APIs
|
|
// see more: https://docs.netbird.io/api/resources/networks
|
|
Networks *NetworksAPI
|
|
|
|
// Routes NetBird routes APIs
|
|
// see more: https://docs.netbird.io/api/resources/routes
|
|
Routes *RoutesAPI
|
|
|
|
// DNS NetBird DNS APIs
|
|
// see more: https://docs.netbird.io/api/resources/dns
|
|
DNS *DNSAPI
|
|
|
|
// DNSZones NetBird DNS Zones APIs
|
|
// see more: https://docs.netbird.io/api/resources/dns-zones
|
|
DNSZones *DNSZonesAPI
|
|
|
|
// GeoLocation NetBird Geo Location APIs
|
|
// see more: https://docs.netbird.io/api/resources/geo-locations
|
|
GeoLocation *GeoLocationAPI
|
|
|
|
// Events NetBird Events APIs
|
|
// see more: https://docs.netbird.io/api/resources/events
|
|
Events *EventsAPI
|
|
|
|
// Billing NetBird Billing APIs for subscriptions, plans, and invoices
|
|
// see more: https://docs.netbird.io/api/resources/billing
|
|
Billing *BillingAPI
|
|
|
|
// MSP NetBird MSP tenant management APIs
|
|
// see more: https://docs.netbird.io/api/resources/msp
|
|
MSP *MSPAPI
|
|
|
|
// EDR NetBird EDR integration APIs (Intune, SentinelOne, Falcon, Huntress)
|
|
// see more: https://docs.netbird.io/api/resources/edr
|
|
EDR *EDRAPI
|
|
|
|
// SCIM NetBird SCIM IDP integration APIs
|
|
// see more: https://docs.netbird.io/api/resources/scim
|
|
SCIM *SCIMAPI
|
|
|
|
// GoogleIDP NetBird Google Workspace IDP integration APIs
|
|
GoogleIDP *GoogleIDPAPI
|
|
|
|
// AzureIDP NetBird Azure AD IDP integration APIs
|
|
AzureIDP *AzureIDPAPI
|
|
|
|
// OktaScimIDP NetBird Okta SCIM IDP integration APIs
|
|
OktaScimIDP *OktaScimIDPAPI
|
|
|
|
// EventStreaming NetBird Event Streaming integration APIs
|
|
// see more: https://docs.netbird.io/api/resources/event-streaming
|
|
EventStreaming *EventStreamingAPI
|
|
|
|
// IdentityProviders NetBird Identity Providers APIs
|
|
// see more: https://docs.netbird.io/api/resources/identity-providers
|
|
IdentityProviders *IdentityProvidersAPI
|
|
|
|
// Ingress NetBird Ingress Peers APIs
|
|
// see more: https://docs.netbird.io/api/resources/ingress-ports
|
|
Ingress *IngressAPI
|
|
|
|
// Instance NetBird Instance API
|
|
// see more: https://docs.netbird.io/api/resources/instance
|
|
Instance *InstanceAPI
|
|
|
|
// ReverseProxyServices NetBird reverse proxy services APIs
|
|
ReverseProxyServices *ReverseProxyServicesAPI
|
|
|
|
// ReverseProxyClusters NetBird reverse proxy clusters APIs
|
|
ReverseProxyClusters *ReverseProxyClustersAPI
|
|
|
|
// ReverseProxyDomains NetBird reverse proxy domains APIs
|
|
ReverseProxyDomains *ReverseProxyDomainsAPI
|
|
}
|
|
|
|
// New initialize new Client instance using PAT token
|
|
func New(managementURL, token string) *Client {
|
|
return NewWithOptions(
|
|
WithManagementURL(managementURL),
|
|
WithPAT(token),
|
|
)
|
|
}
|
|
|
|
// NewWithBearerToken initialize new Client instance using Bearer token type
|
|
func NewWithBearerToken(managementURL, token string) *Client {
|
|
return NewWithOptions(
|
|
WithManagementURL(managementURL),
|
|
WithBearerToken(token),
|
|
)
|
|
}
|
|
|
|
// NewWithOptions initialize new Client instance with options
|
|
func NewWithOptions(opts ...option) *Client {
|
|
client := &Client{
|
|
httpClient: http.DefaultClient,
|
|
}
|
|
|
|
for _, option := range opts {
|
|
option(client)
|
|
}
|
|
|
|
client.initialize()
|
|
return client
|
|
}
|
|
|
|
func (c *Client) initialize() {
|
|
c.Accounts = &AccountsAPI{c}
|
|
c.Users = &UsersAPI{c}
|
|
c.Tokens = &TokensAPI{c}
|
|
c.Peers = &PeersAPI{c}
|
|
c.SetupKeys = &SetupKeysAPI{c}
|
|
c.Groups = &GroupsAPI{c}
|
|
c.Policies = &PoliciesAPI{c}
|
|
c.PostureChecks = &PostureChecksAPI{c}
|
|
c.Networks = &NetworksAPI{c}
|
|
c.Routes = &RoutesAPI{c}
|
|
c.DNS = &DNSAPI{c}
|
|
c.DNSZones = &DNSZonesAPI{c}
|
|
c.GeoLocation = &GeoLocationAPI{c}
|
|
c.Events = &EventsAPI{c}
|
|
c.Billing = &BillingAPI{c}
|
|
c.MSP = &MSPAPI{c}
|
|
c.EDR = &EDRAPI{c}
|
|
c.SCIM = &SCIMAPI{c}
|
|
c.GoogleIDP = &GoogleIDPAPI{c}
|
|
c.AzureIDP = &AzureIDPAPI{c}
|
|
c.OktaScimIDP = &OktaScimIDPAPI{c}
|
|
c.EventStreaming = &EventStreamingAPI{c}
|
|
c.IdentityProviders = &IdentityProvidersAPI{c}
|
|
c.Ingress = &IngressAPI{c}
|
|
c.Instance = &InstanceAPI{c}
|
|
c.ReverseProxyServices = &ReverseProxyServicesAPI{c}
|
|
c.ReverseProxyClusters = &ReverseProxyClustersAPI{c}
|
|
c.ReverseProxyDomains = &ReverseProxyDomainsAPI{c}
|
|
}
|
|
|
|
// NewRequest creates and executes new management API request
|
|
func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Reader, query map[string]string) (*http.Response, error) {
|
|
req, err := http.NewRequestWithContext(ctx, method, c.managementURL+path, body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Add("Authorization", c.authHeader)
|
|
req.Header.Add("Accept", "application/json")
|
|
if body != nil {
|
|
req.Header.Add("Content-Type", "application/json")
|
|
}
|
|
if c.userAgent != "" {
|
|
req.Header.Set("User-Agent", c.userAgent)
|
|
}
|
|
|
|
if len(query) != 0 {
|
|
q := req.URL.Query()
|
|
for k, v := range query {
|
|
q.Add(k, v)
|
|
}
|
|
req.URL.RawQuery = q.Encode()
|
|
}
|
|
|
|
resp, err := c.httpClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.StatusCode > 299 {
|
|
parsedErr, pErr := parseResponse[util.ErrorResponse](resp)
|
|
if pErr != nil {
|
|
return nil, pErr
|
|
}
|
|
return nil, &APIError{
|
|
StatusCode: resp.StatusCode,
|
|
Message: parsedErr.Message,
|
|
}
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
func parseResponse[T any](resp *http.Response) (T, error) {
|
|
var ret T
|
|
if resp.Body == nil {
|
|
return ret, fmt.Errorf("body missing, HTTP Error code %d", resp.StatusCode)
|
|
}
|
|
bs, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return ret, err
|
|
}
|
|
err = json.Unmarshal(bs, &ret)
|
|
if err != nil {
|
|
return ret, fmt.Errorf("error code %d, error unmarshalling body: %w", resp.StatusCode, err)
|
|
}
|
|
|
|
return ret, nil
|
|
}
|