mirror of
https://github.com/netbirdio/netbird.git
synced 2025-03-13 06:08:48 +01:00
Merge branch 'main' into feature/port-forwarding
This commit is contained in:
commit
b2a5b29fb2
@ -2,6 +2,8 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -11,7 +13,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/netbirdio/netbird/client/internal"
|
||||
"github.com/netbirdio/netbird/util/embeddedroots"
|
||||
)
|
||||
|
||||
// HostedGrantType grant type for device flow on Hosted
|
||||
@ -56,6 +61,18 @@ func NewDeviceAuthorizationFlow(config internal.DeviceAuthProviderConfig) (*Devi
|
||||
httpTransport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
httpTransport.MaxIdleConns = 5
|
||||
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil || certPool == nil {
|
||||
log.Debugf("System cert pool not available; falling back to embedded cert, error: %v", err)
|
||||
certPool = embeddedroots.Get()
|
||||
} else {
|
||||
log.Debug("Using system certificate pool.")
|
||||
}
|
||||
|
||||
httpTransport.TLSClientConfig = &tls.Config{
|
||||
RootCAs: certPool,
|
||||
}
|
||||
|
||||
httpClient := &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
Transport: httpTransport,
|
||||
|
@ -1,8 +1,9 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"github.com/magiconair/properties/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConnStatus_String(t *testing.T) {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/magiconair/properties/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/internal/peer/guard"
|
||||
|
2
go.mod
2
go.mod
@ -54,7 +54,6 @@ require (
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/libdns/route53 v1.5.0
|
||||
github.com/libp2p/go-netroute v0.2.1
|
||||
github.com/magiconair/properties v1.8.7
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/mdlayher/socket v0.5.1
|
||||
github.com/miekg/dns v1.1.59
|
||||
@ -185,6 +184,7 @@ require (
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/libdns/libdns v0.2.2 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mdlayher/genetlink v1.3.2 // indirect
|
||||
github.com/mdlayher/netlink v1.7.2 // indirect
|
||||
github.com/mholt/acmez/v2 v2.0.1 // indirect
|
||||
|
54
management/client/rest/accounts.go
Normal file
54
management/client/rest/accounts.go
Normal file
@ -0,0 +1,54 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// AccountsAPI APIs for accounts, do not use directly
|
||||
type AccountsAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all accounts, only returns one account always
|
||||
// See more: https://docs.netbird.io/api/resources/accounts#list-all-accounts
|
||||
func (a *AccountsAPI) List(ctx context.Context) ([]api.Account, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/accounts", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Account](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Update update account settings
|
||||
// See more: https://docs.netbird.io/api/resources/accounts#update-an-account
|
||||
func (a *AccountsAPI) Update(ctx context.Context, accountID string, request api.PutApiAccountsAccountIdJSONRequestBody) (*api.Account, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/accounts/"+accountID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Account](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete account
|
||||
// See more: https://docs.netbird.io/api/resources/accounts#delete-an-account
|
||||
func (a *AccountsAPI) Delete(ctx context.Context, accountID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/accounts/"+accountID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
169
management/client/rest/accounts_test.go
Normal file
169
management/client/rest/accounts_test.go
Normal file
@ -0,0 +1,169 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testAccount = api.Account{
|
||||
Id: "Test",
|
||||
Settings: api.AccountSettings{
|
||||
Extra: &api.AccountExtraSettings{
|
||||
PeerApprovalEnabled: ptr(false),
|
||||
},
|
||||
GroupsPropagationEnabled: ptr(true),
|
||||
JwtGroupsEnabled: ptr(false),
|
||||
PeerInactivityExpiration: 7,
|
||||
PeerInactivityExpirationEnabled: true,
|
||||
PeerLoginExpiration: 24,
|
||||
PeerLoginExpirationEnabled: true,
|
||||
RegularUsersViewBlocked: false,
|
||||
RoutingPeerDnsResolutionEnabled: ptr(false),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestAccounts_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Account{testAccount})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Accounts.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testAccount, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Accounts.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiAccountsAccountIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, *req.Settings.RoutingPeerDnsResolutionEnabled)
|
||||
retBytes, _ := json.Marshal(testAccount)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Accounts.Update(context.Background(), "Test", api.PutApiAccountsAccountIdJSONRequestBody{
|
||||
Settings: api.AccountSettings{
|
||||
RoutingPeerDnsResolutionEnabled: ptr(true),
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testAccount, *ret)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestAccounts_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Accounts.Update(context.Background(), "Test", api.PutApiAccountsAccountIdJSONRequestBody{
|
||||
Settings: api.AccountSettings{
|
||||
RoutingPeerDnsResolutionEnabled: ptr(true),
|
||||
},
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Accounts.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/accounts/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Accounts.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_Integration_List(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
accounts, err := c.Accounts.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, accounts, 1)
|
||||
assert.Equal(t, "bf1c8084-ba50-4ce7-9439-34653001fc3b", accounts[0].Id)
|
||||
assert.Equal(t, false, *accounts[0].Settings.Extra.PeerApprovalEnabled)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccounts_Integration_Update(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
accounts, err := c.Accounts.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, accounts, 1)
|
||||
accounts[0].Settings.JwtAllowGroups = ptr([]string{"test"})
|
||||
account, err := c.Accounts.Update(context.Background(), accounts[0].Id, api.AccountRequest{
|
||||
Settings: accounts[0].Settings,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, accounts[0].Id, account.Id)
|
||||
assert.Equal(t, []string{"test"}, *account.Settings.JwtAllowGroups)
|
||||
})
|
||||
}
|
||||
|
||||
// Account deletion on MySQL and PostgreSQL databases causes unknown errors
|
||||
// func TestAccounts_Integration_Delete(t *testing.T) {
|
||||
// withBlackBoxServer(t, func(c *Client) {
|
||||
// accounts, err := c.Accounts.List(context.Background())
|
||||
// require.NoError(t, err)
|
||||
// assert.Len(t, accounts, 1)
|
||||
// err = c.Accounts.Delete(context.Background(), accounts[0].Id)
|
||||
// require.NoError(t, err)
|
||||
// _, err = c.Accounts.List(context.Background())
|
||||
// assert.Error(t, err)
|
||||
// })
|
||||
// }
|
133
management/client/rest/client.go
Normal file
133
management/client/rest/client.go
Normal file
@ -0,0 +1,133 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
)
|
||||
|
||||
// Client Management service HTTP REST API Client
|
||||
type Client struct {
|
||||
managementURL string
|
||||
authHeader 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/routes
|
||||
DNS *DNSAPI
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// New initialize new Client instance
|
||||
func New(managementURL, token string) *Client {
|
||||
client := &Client{
|
||||
managementURL: managementURL,
|
||||
authHeader: "Token " + token,
|
||||
}
|
||||
client.Accounts = &AccountsAPI{client}
|
||||
client.Users = &UsersAPI{client}
|
||||
client.Tokens = &TokensAPI{client}
|
||||
client.Peers = &PeersAPI{client}
|
||||
client.SetupKeys = &SetupKeysAPI{client}
|
||||
client.Groups = &GroupsAPI{client}
|
||||
client.Policies = &PoliciesAPI{client}
|
||||
client.PostureChecks = &PostureChecksAPI{client}
|
||||
client.Networks = &NetworksAPI{client}
|
||||
client.Routes = &RoutesAPI{client}
|
||||
client.DNS = &DNSAPI{client}
|
||||
client.GeoLocation = &GeoLocationAPI{client}
|
||||
client.Events = &EventsAPI{client}
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *Client) newRequest(ctx context.Context, method, path string, body io.Reader) (*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")
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
parsedErr, pErr := parseResponse[util.ErrorResponse](resp)
|
||||
if pErr != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.New(parsedErr.Message)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func parseResponse[T any](resp *http.Response) (T, error) {
|
||||
var ret T
|
||||
if resp.Body == nil {
|
||||
return ret, errors.New("No body")
|
||||
}
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
err = json.Unmarshal(bs, &ret)
|
||||
|
||||
return ret, err
|
||||
}
|
30
management/client/rest/client_test.go
Normal file
30
management/client/rest/client_test.go
Normal file
@ -0,0 +1,30 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/testing/testing_tools"
|
||||
)
|
||||
|
||||
func withMockClient(callback func(*Client, *http.ServeMux)) {
|
||||
mux := &http.ServeMux{}
|
||||
server := httptest.NewServer(mux)
|
||||
defer server.Close()
|
||||
c := New(server.URL, "ABC")
|
||||
callback(c, mux)
|
||||
}
|
||||
|
||||
func ptr[T any, PT *T](x T) PT {
|
||||
return &x
|
||||
}
|
||||
|
||||
func withBlackBoxServer(t *testing.T, callback func(*Client)) {
|
||||
t.Helper()
|
||||
handler, _, _ := testing_tools.BuildApiBlackBoxWithDBState(t, "../../server/testdata/store.sql", nil, false)
|
||||
server := httptest.NewServer(handler)
|
||||
defer server.Close()
|
||||
c := New(server.URL, "nbp_apTmlmUXHSC4PKmHwtIZNaGr8eqcVI2gMURp")
|
||||
callback(c)
|
||||
}
|
110
management/client/rest/dns.go
Normal file
110
management/client/rest/dns.go
Normal file
@ -0,0 +1,110 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// DNSAPI APIs for DNS Management, do not use directly
|
||||
type DNSAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// ListNameserverGroups list all nameserver groups
|
||||
// See more: https://docs.netbird.io/api/resources/dns#list-all-nameserver-groups
|
||||
func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGroup, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.NameserverGroup](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// GetNameserverGroup get nameserver group info
|
||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-a-nameserver-group
|
||||
func (a *DNSAPI) GetNameserverGroup(ctx context.Context, nameserverGroupID string) (*api.NameserverGroup, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NameserverGroup](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// CreateNameserverGroup create new nameserver group
|
||||
// See more: https://docs.netbird.io/api/resources/dns#create-a-nameserver-group
|
||||
func (a *DNSAPI) CreateNameserverGroup(ctx context.Context, request api.PostApiDnsNameserversJSONRequestBody) (*api.NameserverGroup, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/dns/nameservers", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NameserverGroup](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// UpdateNameserverGroup update nameserver group info
|
||||
// See more: https://docs.netbird.io/api/resources/dns#update-a-nameserver-group
|
||||
func (a *DNSAPI) UpdateNameserverGroup(ctx context.Context, nameserverGroupID string, request api.PutApiDnsNameserversNsgroupIdJSONRequestBody) (*api.NameserverGroup, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/nameservers/"+nameserverGroupID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NameserverGroup](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// DeleteNameserverGroup delete nameserver group
|
||||
// See more: https://docs.netbird.io/api/resources/dns#delete-a-nameserver-group
|
||||
func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSettings get DNS settings
|
||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-dns-settings
|
||||
func (a *DNSAPI) GetSettings(ctx context.Context) (*api.DNSSettings, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/settings", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.DNSSettings](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// UpdateSettings update DNS settings
|
||||
// See more: https://docs.netbird.io/api/resources/dns#update-dns-settings
|
||||
func (a *DNSAPI) UpdateSettings(ctx context.Context, request api.PutApiDnsSettingsJSONRequestBody) (*api.DNSSettings, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/settings", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.DNSSettings](resp)
|
||||
return &ret, err
|
||||
}
|
295
management/client/rest/dns_test.go
Normal file
295
management/client/rest/dns_test.go
Normal file
@ -0,0 +1,295 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testNameserverGroup = api.NameserverGroup{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
}
|
||||
|
||||
testSettings = api.DNSSettings{
|
||||
DisabledManagementGroups: []string{"gone"},
|
||||
}
|
||||
)
|
||||
|
||||
func TestDNSNameserverGroup_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.NameserverGroup{testNameserverGroup})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.ListNameserverGroups(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testNameserverGroup, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.ListNameserverGroups(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testNameserverGroup)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.GetNameserverGroup(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNameserverGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.GetNameserverGroup(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiDnsNameserversJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNameserverGroup)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.CreateNameserverGroup(context.Background(), api.PostApiDnsNameserversJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNameserverGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.CreateNameserverGroup(context.Background(), api.PostApiDnsNameserversJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiDnsNameserversNsgroupIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNameserverGroup)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.UpdateNameserverGroup(context.Background(), "Test", api.PutApiDnsNameserversNsgroupIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNameserverGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.UpdateNameserverGroup(context.Background(), "Test", api.PutApiDnsNameserversNsgroupIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.DNS.DeleteNameserverGroup(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSNameserverGroup_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/nameservers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.DNS.DeleteNameserverGroup(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSSettings_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testSettings)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.GetSettings(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testSettings, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSSettings_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.GetSettings(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSSettings_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiDnsSettingsJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"test"}, req.DisabledManagementGroups)
|
||||
retBytes, _ := json.Marshal(testSettings)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.UpdateSettings(context.Background(), api.PutApiDnsSettingsJSONRequestBody{
|
||||
DisabledManagementGroups: []string{"test"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testSettings, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNSSettings_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/dns/settings", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.DNS.UpdateSettings(context.Background(), api.PutApiDnsSettingsJSONRequestBody{
|
||||
DisabledManagementGroups: []string{"test"},
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDNS_Integration(t *testing.T) {
|
||||
nsGroupReq := api.NameserverGroupRequest{
|
||||
Description: "Test",
|
||||
Enabled: true,
|
||||
Groups: []string{"cs1tnh0hhcjnqoiuebeg"},
|
||||
Name: "test",
|
||||
Nameservers: []api.Nameserver{
|
||||
{
|
||||
Ip: "8.8.8.8",
|
||||
NsType: api.NameserverNsTypeUdp,
|
||||
Port: 53,
|
||||
},
|
||||
},
|
||||
Primary: true,
|
||||
SearchDomainsEnabled: false,
|
||||
}
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
// Create
|
||||
nsGroup, err := c.DNS.CreateNameserverGroup(context.Background(), nsGroupReq)
|
||||
require.NoError(t, err)
|
||||
|
||||
// List
|
||||
nsGroups, err := c.DNS.ListNameserverGroups(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, *nsGroup, nsGroups[0])
|
||||
|
||||
// Update
|
||||
nsGroupReq.Description = "TestUpdate"
|
||||
nsGroup, err = c.DNS.UpdateNameserverGroup(context.Background(), nsGroup.Id, nsGroupReq)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "TestUpdate", nsGroup.Description)
|
||||
|
||||
// Delete
|
||||
err = c.DNS.DeleteNameserverGroup(context.Background(), nsGroup.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
// List again to ensure deletion
|
||||
nsGroups, err = c.DNS.ListNameserverGroups(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, nsGroups, 0)
|
||||
})
|
||||
}
|
24
management/client/rest/events.go
Normal file
24
management/client/rest/events.go
Normal file
@ -0,0 +1,24 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// EventsAPI APIs for Events, do not use directly
|
||||
type EventsAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all events
|
||||
// See more: https://docs.netbird.io/api/resources/events#list-all-events
|
||||
func (a *EventsAPI) List(ctx context.Context) ([]api.Event, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/events", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Event](resp)
|
||||
return ret, err
|
||||
}
|
65
management/client/rest/events_test.go
Normal file
65
management/client/rest/events_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testEvent = api.Event{
|
||||
Activity: "AccountCreate",
|
||||
ActivityCode: api.EventActivityCodeAccountCreate,
|
||||
}
|
||||
)
|
||||
|
||||
func TestEvents_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/events", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Event{testEvent})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Events.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testEvent, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestEvents_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/events", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Events.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEvents_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
// Do something that would trigger any event
|
||||
_, err := c.SetupKeys.Create(context.Background(), api.CreateSetupKeyRequest{
|
||||
Ephemeral: ptr(true),
|
||||
Name: "TestSetupKey",
|
||||
Type: "reusable",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
events, err := c.Events.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, events)
|
||||
})
|
||||
}
|
36
management/client/rest/geo.go
Normal file
36
management/client/rest/geo.go
Normal file
@ -0,0 +1,36 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// GeoLocationAPI APIs for Geo-Location, do not use directly
|
||||
type GeoLocationAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// ListCountries list all country codes
|
||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-country-codes
|
||||
func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Country](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// ListCountryCities Get a list of all English city names for a given country code
|
||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-city-names-by-country
|
||||
func (a *GeoLocationAPI) ListCountryCities(ctx context.Context, countryCode string) ([]api.City, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries/"+countryCode+"/cities", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.City](resp)
|
||||
return ret, err
|
||||
}
|
96
management/client/rest/geo_test.go
Normal file
96
management/client/rest/geo_test.go
Normal file
@ -0,0 +1,96 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testCountry = api.Country{
|
||||
CountryCode: "DE",
|
||||
CountryName: "Germany",
|
||||
}
|
||||
|
||||
testCity = api.City{
|
||||
CityName: "Berlin",
|
||||
GeonameId: 2950158,
|
||||
}
|
||||
)
|
||||
|
||||
func TestGeo_ListCountries_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/locations/countries", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Country{testCountry})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.GeoLocation.ListCountries(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testCountry, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestGeo_ListCountries_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/locations/countries", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.GeoLocation.ListCountries(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGeo_ListCountryCities_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/locations/countries/Test/cities", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.City{testCity})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.GeoLocation.ListCountryCities(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testCity, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestGeo_ListCountryCities_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/locations/countries/Test/cities", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.GeoLocation.ListCountryCities(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGeo_Integration(t *testing.T) {
|
||||
// Blackbox is initialized with empty GeoLocations
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
countries, err := c.GeoLocation.ListCountries(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, countries)
|
||||
|
||||
cities, err := c.GeoLocation.ListCountryCities(context.Background(), "DE")
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, cities)
|
||||
})
|
||||
}
|
82
management/client/rest/groups.go
Normal file
82
management/client/rest/groups.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// GroupsAPI APIs for Groups, do not use directly
|
||||
type GroupsAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all groups
|
||||
// See more: https://docs.netbird.io/api/resources/groups#list-all-groups
|
||||
func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Group](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get group info
|
||||
// See more: https://docs.netbird.io/api/resources/groups#retrieve-a-group
|
||||
func (a *GroupsAPI) Get(ctx context.Context, groupID string) (*api.Group, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups/"+groupID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Group](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new group
|
||||
// See more: https://docs.netbird.io/api/resources/groups#create-a-group
|
||||
func (a *GroupsAPI) Create(ctx context.Context, request api.PostApiGroupsJSONRequestBody) (*api.Group, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/groups", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Group](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update group info
|
||||
// See more: https://docs.netbird.io/api/resources/groups#update-a-group
|
||||
func (a *GroupsAPI) Update(ctx context.Context, groupID string, request api.PutApiGroupsGroupIdJSONRequestBody) (*api.Group, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/groups/"+groupID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Group](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete group
|
||||
// See more: https://docs.netbird.io/api/resources/groups#delete-a-group
|
||||
func (a *GroupsAPI) Delete(ctx context.Context, groupID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/groups/"+groupID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
210
management/client/rest/groups_test.go
Normal file
210
management/client/rest/groups_test.go
Normal file
@ -0,0 +1,210 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testGroup = api.Group{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
PeersCount: 0,
|
||||
}
|
||||
)
|
||||
|
||||
func TestGroups_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Group{testGroup})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testGroup, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testGroup)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiGroupsJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testGroup)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Create(context.Background(), api.PostApiGroupsJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Create(context.Background(), api.PostApiGroupsJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiGroupsGroupIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testGroup)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Update(context.Background(), "Test", api.PutApiGroupsGroupIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testGroup, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Groups.Update(context.Background(), "Test", api.PutApiGroupsGroupIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Groups.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/groups/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Groups.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroups_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
groups, err := c.Groups.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, groups, 1)
|
||||
|
||||
group, err := c.Groups.Create(context.Background(), api.GroupRequest{
|
||||
Name: "Test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test", group.Name)
|
||||
assert.NotEmpty(t, group.Id)
|
||||
|
||||
group, err = c.Groups.Update(context.Background(), group.Id, api.GroupRequest{
|
||||
Name: "Testnt",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Testnt", group.Name)
|
||||
|
||||
err = c.Groups.Delete(context.Background(), group.Id)
|
||||
require.NoError(t, err)
|
||||
|
||||
groups, err = c.Groups.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, groups, 1)
|
||||
})
|
||||
}
|
246
management/client/rest/networks.go
Normal file
246
management/client/rest/networks.go
Normal file
@ -0,0 +1,246 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// NetworksAPI APIs for Networks, do not use directly
|
||||
type NetworksAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all networks
|
||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-networks
|
||||
func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Network](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get network info
|
||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network
|
||||
func (a *NetworksAPI) Get(ctx context.Context, networkID string) (*api.Network, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+networkID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Network](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new network
|
||||
// See more: https://docs.netbird.io/api/resources/networks#create-a-network
|
||||
func (a *NetworksAPI) Create(ctx context.Context, request api.PostApiNetworksJSONRequestBody) (*api.Network, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Network](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update network
|
||||
// See more: https://docs.netbird.io/api/resources/networks#update-a-network
|
||||
func (a *NetworksAPI) Update(ctx context.Context, networkID string, request api.PutApiNetworksNetworkIdJSONRequestBody) (*api.Network, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+networkID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Network](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete network
|
||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network
|
||||
func (a *NetworksAPI) Delete(ctx context.Context, networkID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+networkID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NetworkResourcesAPI APIs for Network Resources, do not use directly
|
||||
type NetworkResourcesAPI struct {
|
||||
c *Client
|
||||
networkID string
|
||||
}
|
||||
|
||||
// Resources APIs for network resources
|
||||
func (a *NetworksAPI) Resources(networkID string) *NetworkResourcesAPI {
|
||||
return &NetworkResourcesAPI{
|
||||
c: a.c,
|
||||
networkID: networkID,
|
||||
}
|
||||
}
|
||||
|
||||
// List list all resources in networks
|
||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-network-resources
|
||||
func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.NetworkResource](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get network resource info
|
||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network-resource
|
||||
func (a *NetworkResourcesAPI) Get(ctx context.Context, networkResourceID string) (*api.NetworkResource, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkResource](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new network resource
|
||||
// See more: https://docs.netbird.io/api/resources/networks#create-a-network-resource
|
||||
func (a *NetworkResourcesAPI) Create(ctx context.Context, request api.PostApiNetworksNetworkIdResourcesJSONRequestBody) (*api.NetworkResource, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/resources", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkResource](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update network resource
|
||||
// See more: https://docs.netbird.io/api/resources/networks#update-a-network-resource
|
||||
func (a *NetworkResourcesAPI) Update(ctx context.Context, networkResourceID string, request api.PutApiNetworksNetworkIdResourcesResourceIdJSONRequestBody) (*api.NetworkResource, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkResource](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete network resource
|
||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network-resource
|
||||
func (a *NetworkResourcesAPI) Delete(ctx context.Context, networkResourceID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NetworkRoutersAPI APIs for Network Routers, do not use directly
|
||||
type NetworkRoutersAPI struct {
|
||||
c *Client
|
||||
networkID string
|
||||
}
|
||||
|
||||
// Routers APIs for network routers
|
||||
func (a *NetworksAPI) Routers(networkID string) *NetworkRoutersAPI {
|
||||
return &NetworkRoutersAPI{
|
||||
c: a.c,
|
||||
networkID: networkID,
|
||||
}
|
||||
}
|
||||
|
||||
// List list all routers in networks
|
||||
// See more: https://docs.netbird.io/api/routers/networks#list-all-network-routers
|
||||
func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.NetworkRouter](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get network router info
|
||||
// See more: https://docs.netbird.io/api/routers/networks#retrieve-a-network-router
|
||||
func (a *NetworkRoutersAPI) Get(ctx context.Context, networkRouterID string) (*api.NetworkRouter, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkRouter](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new network router
|
||||
// See more: https://docs.netbird.io/api/routers/networks#create-a-network-router
|
||||
func (a *NetworkRoutersAPI) Create(ctx context.Context, request api.PostApiNetworksNetworkIdRoutersJSONRequestBody) (*api.NetworkRouter, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/routers", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkRouter](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update network router
|
||||
// See more: https://docs.netbird.io/api/routers/networks#update-a-network-router
|
||||
func (a *NetworkRoutersAPI) Update(ctx context.Context, networkRouterID string, request api.PutApiNetworksNetworkIdRoutersRouterIdJSONRequestBody) (*api.NetworkRouter, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.NetworkRouter](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete network router
|
||||
// See more: https://docs.netbird.io/api/routers/networks#delete-a-network-router
|
||||
func (a *NetworkRoutersAPI) Delete(ctx context.Context, networkRouterID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
589
management/client/rest/networks_test.go
Normal file
589
management/client/rest/networks_test.go
Normal file
@ -0,0 +1,589 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testNetwork = api.Network{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
}
|
||||
|
||||
testNetworkResource = api.NetworkResource{
|
||||
Description: ptr("meaw"),
|
||||
Id: "awa",
|
||||
}
|
||||
|
||||
testNetworkRouter = api.NetworkRouter{
|
||||
Id: "ouch",
|
||||
}
|
||||
)
|
||||
|
||||
func TestNetworks_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Network{testNetwork})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testNetwork, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testNetwork)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetwork, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiNetworksJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNetwork)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Create(context.Background(), api.PostApiNetworksJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetwork, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Create(context.Background(), api.PostApiNetworksJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiNetworksNetworkIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNetwork)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Update(context.Background(), "Test", api.PutApiNetworksNetworkIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetwork, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Update(context.Background(), "Test", api.PutApiNetworksNetworkIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Networks.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Networks.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworks_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
network, err := c.Networks.Create(context.Background(), api.NetworkRequest{
|
||||
Description: ptr("TestNetwork"),
|
||||
Name: "Test",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Test", network.Name)
|
||||
|
||||
networks, err := c.Networks.List(context.Background())
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, networks)
|
||||
|
||||
network, err = c.Networks.Update(context.Background(), "TestID", api.NetworkRequest{
|
||||
Description: ptr("TestNetwork?"),
|
||||
Name: "Test",
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "TestNetwork?", *network.Description)
|
||||
|
||||
err = c.Networks.Delete(context.Background(), "TestID")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.NetworkResource{testNetworkResource})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testNetworkResource, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testNetworkResource)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkResource, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiNetworksNetworkIdResourcesJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNetworkResource)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Create(context.Background(), api.PostApiNetworksNetworkIdResourcesJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkResource, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Create(context.Background(), api.PostApiNetworksNetworkIdResourcesJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiNetworksNetworkIdResourcesResourceIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testNetworkResource)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Update(context.Background(), "Test", api.PutApiNetworksNetworkIdResourcesResourceIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkResource, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Resources("Meow").Update(context.Background(), "Test", api.PutApiNetworksNetworkIdResourcesResourceIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Networks.Resources("Meow").Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/resources/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Networks.Resources("Meow").Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkResources_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
_, err := c.Networks.Resources("TestNetwork").Create(context.Background(), api.NetworkResourceRequest{
|
||||
Address: "test.com",
|
||||
Description: ptr("Description"),
|
||||
Enabled: false,
|
||||
Groups: []string{"test"},
|
||||
Name: "test",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Resources("TestNetwork").List(context.Background())
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Resources("TestNetwork").Get(context.Background(), "TestResource")
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Resources("TestNetwork").Update(context.Background(), "TestResource", api.NetworkResourceRequest{
|
||||
Address: "testnt.com",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = c.Networks.Resources("TestNetwork").Delete(context.Background(), "TestResource")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.NetworkRouter{testNetworkRouter})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testNetworkRouter, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testNetworkRouter)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkRouter, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiNetworksNetworkIdRoutersJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "test", *req.Peer)
|
||||
retBytes, _ := json.Marshal(testNetworkRouter)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Create(context.Background(), api.PostApiNetworksNetworkIdRoutersJSONRequestBody{
|
||||
Peer: ptr("test"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkRouter, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Create(context.Background(), api.PostApiNetworksNetworkIdRoutersJSONRequestBody{
|
||||
Peer: ptr("test"),
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiNetworksNetworkIdRoutersRouterIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "test", *req.Peer)
|
||||
retBytes, _ := json.Marshal(testNetworkRouter)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Update(context.Background(), "Test", api.PutApiNetworksNetworkIdRoutersRouterIdJSONRequestBody{
|
||||
Peer: ptr("test"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testNetworkRouter, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Networks.Routers("Meow").Update(context.Background(), "Test", api.PutApiNetworksNetworkIdRoutersRouterIdJSONRequestBody{
|
||||
Peer: ptr("test"),
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Networks.Routers("Meow").Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/networks/Meow/routers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Networks.Routers("Meow").Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetworkRouters_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
_, err := c.Networks.Routers("TestNetwork").Create(context.Background(), api.NetworkRouterRequest{
|
||||
Enabled: false,
|
||||
Masquerade: false,
|
||||
Metric: 9999,
|
||||
PeerGroups: ptr([]string{"test"}),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Routers("TestNetwork").List(context.Background())
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Routers("TestNetwork").Get(context.Background(), "TestRouter")
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = c.Networks.Routers("TestNetwork").Update(context.Background(), "TestRouter", api.NetworkRouterRequest{
|
||||
Enabled: true,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = c.Networks.Routers("TestNetwork").Delete(context.Background(), "TestRouter")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
78
management/client/rest/peers.go
Normal file
78
management/client/rest/peers.go
Normal file
@ -0,0 +1,78 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// PeersAPI APIs for peers, do not use directly
|
||||
type PeersAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all peers
|
||||
// See more: https://docs.netbird.io/api/resources/peers#list-all-peers
|
||||
func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Peer](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieve a peer
|
||||
// See more: https://docs.netbird.io/api/resources/peers#retrieve-a-peer
|
||||
func (a *PeersAPI) Get(ctx context.Context, peerID string) (*api.Peer, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Peer](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update information for a peer
|
||||
// See more: https://docs.netbird.io/api/resources/peers#update-a-peer
|
||||
func (a *PeersAPI) Update(ctx context.Context, peerID string, request api.PutApiPeersPeerIdJSONRequestBody) (*api.Peer, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/peers/"+peerID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Peer](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete a peer
|
||||
// See more: https://docs.netbird.io/api/resources/peers#delete-a-peer
|
||||
func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/peers/"+peerID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListAccessiblePeers list all peers that the specified peer can connect to within the network
|
||||
// See more: https://docs.netbird.io/api/resources/peers#list-accessible-peers
|
||||
func (a *PeersAPI) ListAccessiblePeers(ctx context.Context, peerID string) ([]api.Peer, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID+"/accessible-peers", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Peer](resp)
|
||||
return ret, err
|
||||
}
|
203
management/client/rest/peers_test.go
Normal file
203
management/client/rest/peers_test.go
Normal file
@ -0,0 +1,203 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testPeer = api.Peer{
|
||||
ApprovalRequired: false,
|
||||
Connected: false,
|
||||
ConnectionIp: "127.0.0.1",
|
||||
DnsLabel: "test",
|
||||
Id: "Test",
|
||||
}
|
||||
)
|
||||
|
||||
func TestPeers_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Peer{testPeer})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testPeer, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testPeer)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPeer, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiPeersPeerIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, req.InactivityExpirationEnabled)
|
||||
retBytes, _ := json.Marshal(testPeer)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.Update(context.Background(), "Test", api.PutApiPeersPeerIdJSONRequestBody{
|
||||
InactivityExpirationEnabled: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPeer, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.Update(context.Background(), "Test", api.PutApiPeersPeerIdJSONRequestBody{
|
||||
InactivityExpirationEnabled: false,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Peers.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Peers.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_ListAccessiblePeers_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test/accessible-peers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Peer{testPeer})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.ListAccessiblePeers(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testPeer, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_ListAccessiblePeers_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/peers/Test/accessible-peers", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Peers.ListAccessiblePeers(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeers_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
peers, err := c.Peers.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, peers)
|
||||
|
||||
peer, err := c.Peers.Get(context.Background(), peers[0].Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peers[0].Id, peer.Id)
|
||||
|
||||
peer, err = c.Peers.Update(context.Background(), peer.Id, api.PeerRequest{
|
||||
LoginExpirationEnabled: true,
|
||||
Name: "Test",
|
||||
SshEnabled: false,
|
||||
ApprovalRequired: ptr(false),
|
||||
InactivityExpirationEnabled: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, peer.LoginExpirationEnabled)
|
||||
|
||||
accessiblePeers, err := c.Peers.ListAccessiblePeers(context.Background(), peer.Id)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, accessiblePeers)
|
||||
|
||||
err = c.Peers.Delete(context.Background(), peer.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
82
management/client/rest/policies.go
Normal file
82
management/client/rest/policies.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// PoliciesAPI APIs for Policies, do not use directly
|
||||
type PoliciesAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all policies
|
||||
// See more: https://docs.netbird.io/api/resources/policies#list-all-policies
|
||||
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Policy](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get policy info
|
||||
// See more: https://docs.netbird.io/api/resources/policies#retrieve-a-policy
|
||||
func (a *PoliciesAPI) Get(ctx context.Context, policyID string) (*api.Policy, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies/"+policyID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Policy](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new policy
|
||||
// See more: https://docs.netbird.io/api/resources/policies#create-a-policy
|
||||
func (a *PoliciesAPI) Create(ctx context.Context, request api.PostApiPoliciesJSONRequestBody) (*api.Policy, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/policies", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Policy](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update policy info
|
||||
// See more: https://docs.netbird.io/api/resources/policies#update-a-policy
|
||||
func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.PutApiPoliciesPolicyIdJSONRequestBody) (*api.Policy, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/policies/"+policyID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Policy](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete policy
|
||||
// See more: https://docs.netbird.io/api/resources/policies#delete-a-policy
|
||||
func (a *PoliciesAPI) Delete(ctx context.Context, policyID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/policies/"+policyID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
236
management/client/rest/policies_test.go
Normal file
236
management/client/rest/policies_test.go
Normal file
@ -0,0 +1,236 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testPolicy = api.Policy{
|
||||
Name: "wow",
|
||||
Id: ptr("Test"),
|
||||
Enabled: false,
|
||||
}
|
||||
)
|
||||
|
||||
func TestPolicies_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Policy{testPolicy})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testPolicy, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testPolicy)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPolicy, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiPoliciesPolicyIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testPolicy)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Create(context.Background(), api.PostApiPoliciesJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPolicy, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Create(context.Background(), api.PostApiPoliciesJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiPoliciesPolicyIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testPolicy)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Update(context.Background(), "Test", api.PutApiPoliciesPolicyIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPolicy, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Policies.Update(context.Background(), "Test", api.PutApiPoliciesPolicyIdJSONRequestBody{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Policies.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/policies/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Policies.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestPolicies_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
policies, err := c.Policies.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, policies)
|
||||
|
||||
policy, err := c.Policies.Get(context.Background(), *policies[0].Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, *policies[0].Id, *policy.Id)
|
||||
|
||||
policy, err = c.Policies.Update(context.Background(), *policy.Id, api.PolicyCreate{
|
||||
Description: ptr("Test Policy"),
|
||||
Enabled: false,
|
||||
Name: "Test",
|
||||
Rules: []api.PolicyRuleUpdate{
|
||||
{
|
||||
Action: api.PolicyRuleUpdateAction(policy.Rules[0].Action),
|
||||
Bidirectional: true,
|
||||
Description: ptr("Test Policy"),
|
||||
Sources: ptr([]string{(*policy.Rules[0].Sources)[0].Id}),
|
||||
Destinations: ptr([]string{(*policy.Rules[0].Destinations)[0].Id}),
|
||||
Enabled: false,
|
||||
Protocol: api.PolicyRuleUpdateProtocolAll,
|
||||
},
|
||||
},
|
||||
SourcePostureChecks: nil,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test Policy", *policy.Rules[0].Description)
|
||||
|
||||
policy, err = c.Policies.Create(context.Background(), api.PolicyUpdate{
|
||||
Description: ptr("Test Policy 2"),
|
||||
Enabled: false,
|
||||
Name: "Test",
|
||||
Rules: []api.PolicyRuleUpdate{
|
||||
{
|
||||
Action: api.PolicyRuleUpdateAction(policy.Rules[0].Action),
|
||||
Bidirectional: true,
|
||||
Description: ptr("Test Policy 2"),
|
||||
Sources: ptr([]string{(*policy.Rules[0].Sources)[0].Id}),
|
||||
Destinations: ptr([]string{(*policy.Rules[0].Destinations)[0].Id}),
|
||||
Enabled: false,
|
||||
Protocol: api.PolicyRuleUpdateProtocolAll,
|
||||
},
|
||||
},
|
||||
SourcePostureChecks: nil,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = c.Policies.Delete(context.Background(), *policy.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
82
management/client/rest/posturechecks.go
Normal file
82
management/client/rest/posturechecks.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// PostureChecksAPI APIs for PostureChecks, do not use directly
|
||||
type PostureChecksAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all posture checks
|
||||
// See more: https://docs.netbird.io/api/resources/posture-checks#list-all-posture-checks
|
||||
func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.PostureCheck](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get posture check info
|
||||
// See more: https://docs.netbird.io/api/resources/posture-checks#retrieve-a-posture-check
|
||||
func (a *PostureChecksAPI) Get(ctx context.Context, postureCheckID string) (*api.PostureCheck, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks/"+postureCheckID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.PostureCheck](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new posture check
|
||||
// See more: https://docs.netbird.io/api/resources/posture-checks#create-a-posture-check
|
||||
func (a *PostureChecksAPI) Create(ctx context.Context, request api.PostApiPostureChecksJSONRequestBody) (*api.PostureCheck, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/posture-checks", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.PostureCheck](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update posture check info
|
||||
// See more: https://docs.netbird.io/api/resources/posture-checks#update-a-posture-check
|
||||
func (a *PostureChecksAPI) Update(ctx context.Context, postureCheckID string, request api.PutApiPostureChecksPostureCheckIdJSONRequestBody) (*api.PostureCheck, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/posture-checks/"+postureCheckID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.PostureCheck](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete posture check
|
||||
// See more: https://docs.netbird.io/api/resources/posture-checks#delete-a-posture-check
|
||||
func (a *PostureChecksAPI) Delete(ctx context.Context, postureCheckID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/posture-checks/"+postureCheckID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
228
management/client/rest/posturechecks_test.go
Normal file
228
management/client/rest/posturechecks_test.go
Normal file
@ -0,0 +1,228 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testPostureCheck = api.PostureCheck{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
}
|
||||
)
|
||||
|
||||
func TestPostureChecks_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.PostureCheck{testPostureCheck})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testPostureCheck, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testPostureCheck)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPostureCheck, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostureCheckUpdate
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testPostureCheck)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Create(context.Background(), api.PostureCheckUpdate{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPostureCheck, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Create(context.Background(), api.PostureCheckUpdate{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostureCheckUpdate
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "weaw", req.Name)
|
||||
retBytes, _ := json.Marshal(testPostureCheck)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Update(context.Background(), "Test", api.PostureCheckUpdate{
|
||||
Name: "weaw",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testPostureCheck, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.PostureChecks.Update(context.Background(), "Test", api.PostureCheckUpdate{
|
||||
Name: "weaw",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.PostureChecks.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/posture-checks/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.PostureChecks.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostureChecks_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
check, err := c.PostureChecks.Create(context.Background(), api.PostureCheckUpdate{
|
||||
Name: "Test",
|
||||
Description: "Testing",
|
||||
Checks: &api.Checks{
|
||||
OsVersionCheck: &api.OSVersionCheck{
|
||||
Windows: &api.MinKernelVersionCheck{
|
||||
MinKernelVersion: "0.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test", check.Name)
|
||||
|
||||
checks, err := c.PostureChecks.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, checks, 1)
|
||||
|
||||
check, err = c.PostureChecks.Update(context.Background(), check.Id, api.PostureCheckUpdate{
|
||||
Name: "Tests",
|
||||
Description: "Testings",
|
||||
Checks: &api.Checks{
|
||||
GeoLocationCheck: &api.GeoLocationCheck{
|
||||
Action: api.GeoLocationCheckActionAllow, Locations: []api.Location{
|
||||
{
|
||||
CityName: ptr("Cairo"),
|
||||
CountryCode: "EG",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Testings", *check.Description)
|
||||
|
||||
check, err = c.PostureChecks.Get(context.Background(), check.Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Tests", check.Name)
|
||||
|
||||
err = c.PostureChecks.Delete(context.Background(), check.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
82
management/client/rest/routes.go
Normal file
82
management/client/rest/routes.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// RoutesAPI APIs for Routes, do not use directly
|
||||
type RoutesAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all routes
|
||||
// See more: https://docs.netbird.io/api/resources/routes#list-all-routes
|
||||
func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.Route](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get route info
|
||||
// See more: https://docs.netbird.io/api/resources/routes#retrieve-a-route
|
||||
func (a *RoutesAPI) Get(ctx context.Context, routeID string) (*api.Route, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes/"+routeID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Route](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create create new route
|
||||
// See more: https://docs.netbird.io/api/resources/routes#create-a-route
|
||||
func (a *RoutesAPI) Create(ctx context.Context, request api.PostApiRoutesJSONRequestBody) (*api.Route, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/routes", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Route](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update route info
|
||||
// See more: https://docs.netbird.io/api/resources/routes#update-a-route
|
||||
func (a *RoutesAPI) Update(ctx context.Context, routeID string, request api.PutApiRoutesRouteIdJSONRequestBody) (*api.Route, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/routes/"+routeID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.Route](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete route
|
||||
// See more: https://docs.netbird.io/api/resources/routes#delete-a-route
|
||||
func (a *RoutesAPI) Delete(ctx context.Context, routeID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/routes/"+routeID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
226
management/client/rest/routes_test.go
Normal file
226
management/client/rest/routes_test.go
Normal file
@ -0,0 +1,226 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testRoute = api.Route{
|
||||
Id: "Test",
|
||||
Domains: ptr([]string{"google.com"}),
|
||||
}
|
||||
)
|
||||
|
||||
func TestRoutes_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.Route{testRoute})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testRoute, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testRoute)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testRoute, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiRoutesJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "meow", req.Description)
|
||||
retBytes, _ := json.Marshal(testRoute)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Create(context.Background(), api.PostApiRoutesJSONRequestBody{
|
||||
Description: "meow",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testRoute, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Create(context.Background(), api.PostApiRoutesJSONRequestBody{
|
||||
Description: "meow",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiRoutesRouteIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "meow", req.Description)
|
||||
retBytes, _ := json.Marshal(testRoute)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Update(context.Background(), "Test", api.PutApiRoutesRouteIdJSONRequestBody{
|
||||
Description: "meow",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testRoute, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Routes.Update(context.Background(), "Test", api.PutApiRoutesRouteIdJSONRequestBody{
|
||||
Description: "meow",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Routes.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/routes/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Routes.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestRoutes_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
route, err := c.Routes.Create(context.Background(), api.RouteRequest{
|
||||
Description: "Meow",
|
||||
Enabled: false,
|
||||
Groups: []string{"cs1tnh0hhcjnqoiuebeg"},
|
||||
PeerGroups: ptr([]string{"cs1tnh0hhcjnqoiuebeg"}),
|
||||
Domains: ptr([]string{"google.com"}),
|
||||
Masquerade: true,
|
||||
Metric: 9999,
|
||||
KeepRoute: false,
|
||||
NetworkId: "Test",
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test", route.NetworkId)
|
||||
|
||||
routes, err := c.Routes.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, routes, 1)
|
||||
|
||||
route, err = c.Routes.Update(context.Background(), route.Id, api.RouteRequest{
|
||||
Description: "Testings",
|
||||
Enabled: false,
|
||||
Groups: []string{"cs1tnh0hhcjnqoiuebeg"},
|
||||
PeerGroups: ptr([]string{"cs1tnh0hhcjnqoiuebeg"}),
|
||||
Domains: ptr([]string{"google.com"}),
|
||||
Masquerade: true,
|
||||
Metric: 9999,
|
||||
KeepRoute: false,
|
||||
NetworkId: "Tests",
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Testings", route.Description)
|
||||
|
||||
route, err = c.Routes.Get(context.Background(), route.Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Tests", route.NetworkId)
|
||||
|
||||
err = c.Routes.Delete(context.Background(), route.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
82
management/client/rest/setupkeys.go
Normal file
82
management/client/rest/setupkeys.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// SetupKeysAPI APIs for Setup keys, do not use directly
|
||||
type SetupKeysAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all setup keys
|
||||
// See more: https://docs.netbird.io/api/resources/setup-keys#list-all-setup-keys
|
||||
func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.SetupKey](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get setup key info
|
||||
// See more: https://docs.netbird.io/api/resources/setup-keys#retrieve-a-setup-key
|
||||
func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKey, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys/"+setupKeyID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.SetupKey](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create generate new Setup Key
|
||||
// See more: https://docs.netbird.io/api/resources/setup-keys#create-a-setup-key
|
||||
func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJSONRequestBody) (*api.SetupKeyClear, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/setup-keys", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.SetupKeyClear](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update generate new Setup Key
|
||||
// See more: https://docs.netbird.io/api/resources/setup-keys#update-a-setup-key
|
||||
func (a *SetupKeysAPI) Update(ctx context.Context, setupKeyID string, request api.PutApiSetupKeysKeyIdJSONRequestBody) (*api.SetupKey, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/setup-keys/"+setupKeyID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.SetupKey](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete setup key
|
||||
// See more: https://docs.netbird.io/api/resources/setup-keys#delete-a-setup-key
|
||||
func (a *SetupKeysAPI) Delete(ctx context.Context, setupKeyID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/setup-keys/"+setupKeyID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
227
management/client/rest/setupkeys_test.go
Normal file
227
management/client/rest/setupkeys_test.go
Normal file
@ -0,0 +1,227 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testSetupKey = api.SetupKey{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
AutoGroups: []string{"meow"},
|
||||
Ephemeral: true,
|
||||
}
|
||||
|
||||
testSteupKeyGenerated = api.SetupKeyClear{
|
||||
Id: "Test",
|
||||
Name: "wow",
|
||||
AutoGroups: []string{"meow"},
|
||||
Ephemeral: true,
|
||||
Key: "shhh",
|
||||
}
|
||||
)
|
||||
|
||||
func TestSetupKeys_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.SetupKey{testSetupKey})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testSetupKey, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testSetupKey)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Get(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testSetupKey, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Get(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiSetupKeysJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, req.ExpiresIn)
|
||||
retBytes, _ := json.Marshal(testSteupKeyGenerated)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Create(context.Background(), api.PostApiSetupKeysJSONRequestBody{
|
||||
ExpiresIn: 5,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testSteupKeyGenerated, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Create(context.Background(), api.PostApiSetupKeysJSONRequestBody{
|
||||
ExpiresIn: 5,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiSetupKeysKeyIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, req.Revoked)
|
||||
retBytes, _ := json.Marshal(testSetupKey)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Update(context.Background(), "Test", api.PutApiSetupKeysKeyIdJSONRequestBody{
|
||||
Revoked: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testSetupKey, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.SetupKeys.Update(context.Background(), "Test", api.PutApiSetupKeysKeyIdJSONRequestBody{
|
||||
Revoked: true,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.SetupKeys.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/setup-keys/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.SetupKeys.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetupKeys_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
group, err := c.Groups.Create(context.Background(), api.GroupRequest{
|
||||
Name: "Test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
skClear, err := c.SetupKeys.Create(context.Background(), api.CreateSetupKeyRequest{
|
||||
AutoGroups: []string{group.Id},
|
||||
Ephemeral: ptr(false),
|
||||
Name: "test",
|
||||
Type: "reusable",
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, skClear.Valid)
|
||||
|
||||
keys, err := c.SetupKeys.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, keys, 2)
|
||||
|
||||
sk, err := c.SetupKeys.Update(context.Background(), skClear.Id, api.SetupKeyRequest{
|
||||
Revoked: true,
|
||||
AutoGroups: []string{group.Id},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
sk, err = c.SetupKeys.Get(context.Background(), sk.Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, sk.Valid)
|
||||
|
||||
err = c.SetupKeys.Delete(context.Background(), sk.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
66
management/client/rest/tokens.go
Normal file
66
management/client/rest/tokens.go
Normal file
@ -0,0 +1,66 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// TokensAPI APIs for PATs, do not use directly
|
||||
type TokensAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list user tokens
|
||||
// See more: https://docs.netbird.io/api/resources/tokens#list-all-tokens
|
||||
func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAccessToken, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.PersonalAccessToken](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get get user token info
|
||||
// See more: https://docs.netbird.io/api/resources/tokens#retrieve-a-token
|
||||
func (a *TokensAPI) Get(ctx context.Context, userID, tokenID string) (*api.PersonalAccessToken, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.PersonalAccessToken](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Create generate new PAT for user
|
||||
// See more: https://docs.netbird.io/api/resources/tokens#create-a-token
|
||||
func (a *TokensAPI) Create(ctx context.Context, userID string, request api.PostApiUsersUserIdTokensJSONRequestBody) (*api.PersonalAccessTokenGenerated, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/tokens", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.PersonalAccessTokenGenerated](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete user token
|
||||
// See more: https://docs.netbird.io/api/resources/tokens#delete-a-token
|
||||
func (a *TokensAPI) Delete(ctx context.Context, userID, tokenID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
175
management/client/rest/tokens_test.go
Normal file
175
management/client/rest/tokens_test.go
Normal file
@ -0,0 +1,175 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testToken = api.PersonalAccessToken{
|
||||
Id: "Test",
|
||||
CreatedAt: time.Time{},
|
||||
CreatedBy: "meow",
|
||||
ExpirationDate: time.Time{},
|
||||
LastUsed: nil,
|
||||
Name: "wow",
|
||||
}
|
||||
|
||||
testTokenGenerated = api.PersonalAccessTokenGenerated{
|
||||
PersonalAccessToken: testToken,
|
||||
PlainToken: "shhh",
|
||||
}
|
||||
)
|
||||
|
||||
func TestTokens_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.PersonalAccessToken{testToken})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.List(context.Background(), "meow")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testToken, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.List(context.Background(), "meow")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Get_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(testToken)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.Get(context.Background(), "meow", "Test")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testToken, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Get_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.Get(context.Background(), "meow", "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiUsersUserIdTokensJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 5, req.ExpiresIn)
|
||||
retBytes, _ := json.Marshal(testTokenGenerated)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.Create(context.Background(), "meow", api.PostApiUsersUserIdTokensJSONRequestBody{
|
||||
ExpiresIn: 5,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testTokenGenerated, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Tokens.Create(context.Background(), "meow", api.PostApiUsersUserIdTokensJSONRequestBody{
|
||||
ExpiresIn: 5,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Tokens.Delete(context.Background(), "meow", "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/meow/tokens/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Tokens.Delete(context.Background(), "meow", "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestTokens_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
tokenClear, err := c.Tokens.Create(context.Background(), "a23efe53-63fb-11ec-90d6-0242ac120003", api.PersonalAccessTokenRequest{
|
||||
Name: "Test",
|
||||
ExpiresIn: 365,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test", tokenClear.PersonalAccessToken.Name)
|
||||
|
||||
tokens, err := c.Tokens.List(context.Background(), "a23efe53-63fb-11ec-90d6-0242ac120003")
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, tokens, 2)
|
||||
|
||||
token, err := c.Tokens.Get(context.Background(), "a23efe53-63fb-11ec-90d6-0242ac120003", tokenClear.PersonalAccessToken.Id)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Test", token.Name)
|
||||
|
||||
err = c.Tokens.Delete(context.Background(), "a23efe53-63fb-11ec-90d6-0242ac120003", token.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
82
management/client/rest/users.go
Normal file
82
management/client/rest/users.go
Normal file
@ -0,0 +1,82 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
// UsersAPI APIs for users, do not use directly
|
||||
type UsersAPI struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// List list all users, only returns one user always
|
||||
// See more: https://docs.netbird.io/api/resources/users#list-all-users
|
||||
func (a *UsersAPI) List(ctx context.Context) ([]api.User, error) {
|
||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[[]api.User](resp)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Create create user
|
||||
// See more: https://docs.netbird.io/api/resources/users#create-a-user
|
||||
func (a *UsersAPI) Create(ctx context.Context, request api.PostApiUsersJSONRequestBody) (*api.User, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users", bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.User](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Update update user settings
|
||||
// See more: https://docs.netbird.io/api/resources/users#update-a-user
|
||||
func (a *UsersAPI) Update(ctx context.Context, userID string, request api.PutApiUsersUserIdJSONRequestBody) (*api.User, error) {
|
||||
requestBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/users/"+userID, bytes.NewReader(requestBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ret, err := parseResponse[api.User](resp)
|
||||
return &ret, err
|
||||
}
|
||||
|
||||
// Delete delete user
|
||||
// See more: https://docs.netbird.io/api/resources/users#delete-a-user
|
||||
func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResendInvitation resend user invitation
|
||||
// See more: https://docs.netbird.io/api/resources/users#resend-user-invitation
|
||||
func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/invite", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
222
management/client/rest/users_test.go
Normal file
222
management/client/rest/users_test.go
Normal file
@ -0,0 +1,222 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
testUser = api.User{
|
||||
Id: "Test",
|
||||
AutoGroups: []string{"test-group"},
|
||||
Email: "test@test.com",
|
||||
IsBlocked: false,
|
||||
IsCurrent: ptr(false),
|
||||
IsServiceUser: ptr(false),
|
||||
Issued: ptr("api"),
|
||||
LastLogin: &time.Time{},
|
||||
Name: "M. Essam",
|
||||
Permissions: &api.UserPermissions{
|
||||
DashboardView: ptr(api.UserPermissionsDashboardViewFull),
|
||||
},
|
||||
Role: "user",
|
||||
Status: api.UserStatusActive,
|
||||
}
|
||||
)
|
||||
|
||||
func TestUsers_List_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal([]api.User{testUser})
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, ret, 1)
|
||||
assert.Equal(t, testUser, ret[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_List_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.List(context.Background())
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Empty(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Create_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PostApiUsersJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"meow"}, req.AutoGroups)
|
||||
retBytes, _ := json.Marshal(testUser)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.Create(context.Background(), api.PostApiUsersJSONRequestBody{
|
||||
AutoGroups: []string{"meow"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testUser, *ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Create_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.Create(context.Background(), api.PostApiUsersJSONRequestBody{
|
||||
AutoGroups: []string{"meow"},
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Update_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "PUT", r.Method)
|
||||
reqBytes, err := io.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
var req api.PutApiUsersUserIdJSONRequestBody
|
||||
err = json.Unmarshal(reqBytes, &req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, req.IsBlocked)
|
||||
retBytes, _ := json.Marshal(testUser)
|
||||
_, err = w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.Update(context.Background(), "Test", api.PutApiUsersUserIdJSONRequestBody{
|
||||
IsBlocked: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, testUser, *ret)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestUsers_Update_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "No", Code: 400})
|
||||
w.WriteHeader(400)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
ret, err := c.Users.Update(context.Background(), "Test", api.PutApiUsersUserIdJSONRequestBody{
|
||||
IsBlocked: true,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "No", err.Error())
|
||||
assert.Nil(t, ret)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Delete_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "DELETE", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Users.Delete(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Delete_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Users.Delete(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_ResendInvitation_200(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test/invite", func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "POST", r.Method)
|
||||
w.WriteHeader(200)
|
||||
})
|
||||
err := c.Users.ResendInvitation(context.Background(), "Test")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_ResendInvitation_Err(t *testing.T) {
|
||||
withMockClient(func(c *Client, mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/users/Test/invite", func(w http.ResponseWriter, r *http.Request) {
|
||||
retBytes, _ := json.Marshal(util.ErrorResponse{Message: "Not found", Code: 404})
|
||||
w.WriteHeader(404)
|
||||
_, err := w.Write(retBytes)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
err := c.Users.ResendInvitation(context.Background(), "Test")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Not found", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestUsers_Integration(t *testing.T) {
|
||||
withBlackBoxServer(t, func(c *Client) {
|
||||
user, err := c.Users.Create(context.Background(), api.UserCreateRequest{
|
||||
AutoGroups: []string{},
|
||||
Email: ptr("test@example.com"),
|
||||
IsServiceUser: true,
|
||||
Name: ptr("Nobody"),
|
||||
Role: "user",
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Nobody", user.Name)
|
||||
|
||||
users, err := c.Users.List(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, users)
|
||||
|
||||
user, err = c.Users.Update(context.Background(), user.Id, api.UserRequest{
|
||||
AutoGroups: []string{},
|
||||
Role: "admin",
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "admin", user.Role)
|
||||
|
||||
err = c.Users.Delete(context.Background(), user.Id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
@ -7,15 +7,14 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/configs"
|
||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/http/configs"
|
||||
"github.com/netbirdio/netbird/management/server/http/util"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
)
|
||||
|
||||
// handler is a handler that returns groups of the account
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/magiconair/properties/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
|
@ -10,17 +10,14 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
|
||||
"github.com/magiconair/properties/assert"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
)
|
||||
|
||||
func initPoliciesTestData(policies ...*types.Policy) *handler {
|
||||
|
@ -11,21 +11,19 @@ import (
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/util"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/netbirdio/netbird/management/domain"
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
"github.com/netbirdio/netbird/management/server/util"
|
||||
"github.com/netbirdio/netbird/route"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/magiconair/properties/assert"
|
||||
|
||||
"github.com/netbirdio/netbird/management/domain"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
)
|
||||
|
||||
const (
|
||||
|
5
management/server/testdata/store.sql
vendored
5
management/server/testdata/store.sql
vendored
@ -19,6 +19,7 @@ CREATE INDEX `idx_accounts_domain` ON `accounts`(`domain`);
|
||||
CREATE INDEX `idx_setup_keys_account_id` ON `setup_keys`(`account_id`);
|
||||
CREATE INDEX `idx_peers_key` ON `peers`(`key`);
|
||||
CREATE INDEX `idx_peers_account_id` ON `peers`(`account_id`);
|
||||
CREATE INDEX `idx_peers_account_id_ip` ON `peers`(`account_id`,`ip`);
|
||||
CREATE INDEX `idx_users_account_id` ON `users`(`account_id`);
|
||||
CREATE INDEX `idx_personal_access_tokens_user_id` ON `personal_access_tokens`(`user_id`);
|
||||
CREATE INDEX `idx_groups_account_id` ON `groups`(`account_id`);
|
||||
@ -39,8 +40,11 @@ CREATE INDEX `idx_networks_account_id` ON `networks`(`account_id`);
|
||||
INSERT INTO accounts VALUES('bf1c8084-ba50-4ce7-9439-34653001fc3b','','2024-10-02 16:03:06.778746+02:00','test.com','private',1,'af1c8024-ha40-4ce2-9418-34653101fc3c','{"IP":"100.64.0.0","Mask":"//8AAA=="}','',0,'[]',0,86400000000000,0,0,0,'',NULL,NULL,NULL);
|
||||
INSERT INTO "groups" VALUES('cs1tnh0hhcjnqoiuebeg','bf1c8084-ba50-4ce7-9439-34653001fc3b','All','api','[]',0,'');
|
||||
INSERT INTO setup_keys VALUES('','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBB','Default key','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["cs1tnh0hhcjnqoiuebeg"]',0,0);
|
||||
INSERT INTO users VALUES('a23efe53-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','owner',0,0,'','[]',0,NULL,'2024-10-02 16:03:06.779156+02:00','api',0,'');
|
||||
INSERT INTO users VALUES('edafee4e-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','admin',0,0,'','[]',0,NULL,'2024-10-02 16:03:06.779156+02:00','api',0,'');
|
||||
INSERT INTO users VALUES('f4f6d672-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','user',0,0,'','[]',0,NULL,'2024-10-02 16:03:06.779156+02:00','api',0,'');
|
||||
-- Unhashed PAT is "nbp_apTmlmUXHSC4PKmHwtIZNaGr8eqcVI2gMURp"
|
||||
INSERT INTO personal_access_tokens VALUES('9dj38s35-63fb-11ec-90d6-0242ac120004','a23efe53-63fb-11ec-90d6-0242ac120003','','smJvzexPcQ3NRezrVDUmF++0XqvFvXzx8Rsn2y9r1z0=','5023-02-27 00:00:00+00:00','user','2023-01-01 00:00:00+00:00','2023-02-01 00:00:00+00:00');
|
||||
INSERT INTO personal_access_tokens VALUES('9dj38s35-63fb-11ec-90d6-0242ac120003','f4f6d672-63fb-11ec-90d6-0242ac120003','','SoMeHaShEdToKeN','2023-02-27 00:00:00+00:00','user','2023-01-01 00:00:00+00:00','2023-02-01 00:00:00+00:00');
|
||||
INSERT INTO installations VALUES(1,'');
|
||||
INSERT INTO policies VALUES('cs1tnh0hhcjnqoiuebf0','bf1c8084-ba50-4ce7-9439-34653001fc3b','Default','This is a default rule that allows connections between all the resources',1,'[]');
|
||||
@ -48,3 +52,4 @@ INSERT INTO policy_rules VALUES('cs387mkv2d4bgq41b6n0','cs1tnh0hhcjnqoiuebf0','D
|
||||
INSERT INTO network_routers VALUES('ctc20ji7qv9ck2sebc80','ct286bi7qv930dsrrug0','bf1c8084-ba50-4ce7-9439-34653001fc3b','cs1tnh0hhcjnqoiuebeg',NULL,0,0);
|
||||
INSERT INTO network_resources VALUES ('ctc4nci7qv9061u6ilfg','ct286bi7qv930dsrrug0','bf1c8084-ba50-4ce7-9439-34653001fc3b','Host','192.168.1.1');
|
||||
INSERT INTO networks VALUES('ct286bi7qv930dsrrug0','bf1c8084-ba50-4ce7-9439-34653001fc3b','Test Network','Test Network');
|
||||
INSERT INTO peers VALUES('ct286bi7qv930dsrrug0','bf1c8084-ba50-4ce7-9439-34653001fc3b','','','192.168.0.0','','','','','','','','','','','','','','','','','test','test','2023-01-01 00:00:00+00:00',0,0,0,'a23efe53-63fb-11ec-90d6-0242ac120003','',0,0,'2023-01-01 00:00:00+00:00','2023-01-01 00:00:00+00:00',0,'','','',0);
|
||||
|
@ -2,6 +2,8 @@ package ws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@ -13,6 +15,7 @@ import (
|
||||
"nhooyr.io/websocket"
|
||||
|
||||
"github.com/netbirdio/netbird/relay/server/listener/ws"
|
||||
"github.com/netbirdio/netbird/util/embeddedroots"
|
||||
nbnet "github.com/netbirdio/netbird/util/net"
|
||||
)
|
||||
|
||||
@ -66,10 +69,19 @@ func prepareURL(address string) (string, error) {
|
||||
func httpClientNbDialer() *http.Client {
|
||||
customDialer := nbnet.NewDialer()
|
||||
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil || certPool == nil {
|
||||
log.Debugf("System cert pool not available; falling back to embedded cert, error: %v", err)
|
||||
certPool = embeddedroots.Get()
|
||||
}
|
||||
|
||||
customTransport := &http.Transport{
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return customDialer.DialContext(ctx, network, addr)
|
||||
},
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: certPool,
|
||||
},
|
||||
}
|
||||
|
||||
return &http.Client{
|
||||
|
@ -2,11 +2,25 @@
|
||||
|
||||
package tls
|
||||
|
||||
import "crypto/tls"
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/netbirdio/netbird/util/embeddedroots"
|
||||
)
|
||||
|
||||
func ClientQUICTLSConfig() *tls.Config {
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil || certPool == nil {
|
||||
log.Debugf("System cert pool not available; falling back to embedded cert, error: %v", err)
|
||||
certPool = embeddedroots.Get()
|
||||
}
|
||||
|
||||
return &tls.Config{
|
||||
InsecureSkipVerify: true, // Debug mode allows insecure connections
|
||||
NextProtos: []string{nbalpn}, // Ensure this matches the server's ALPN
|
||||
RootCAs: certPool,
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,24 @@
|
||||
|
||||
package tls
|
||||
|
||||
import "crypto/tls"
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/netbirdio/netbird/util/embeddedroots"
|
||||
)
|
||||
|
||||
func ClientQUICTLSConfig() *tls.Config {
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil || certPool == nil {
|
||||
log.Debugf("System cert pool not available; falling back to embedded cert, error: %v", err)
|
||||
certPool = embeddedroots.Get()
|
||||
}
|
||||
|
||||
return &tls.Config{
|
||||
NextProtos: []string{nbalpn},
|
||||
RootCAs: certPool,
|
||||
}
|
||||
}
|
||||
|
42
util/embeddedroots/embeddedroots.go
Normal file
42
util/embeddedroots/embeddedroots.go
Normal file
@ -0,0 +1,42 @@
|
||||
package embeddedroots
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
_ "embed"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func Get() *x509.CertPool {
|
||||
rootsVar.load()
|
||||
return rootsVar.p
|
||||
}
|
||||
|
||||
type roots struct {
|
||||
once sync.Once
|
||||
p *x509.CertPool
|
||||
}
|
||||
|
||||
var rootsVar roots
|
||||
|
||||
func (r *roots) load() {
|
||||
r.once.Do(func() {
|
||||
p := x509.NewCertPool()
|
||||
p.AppendCertsFromPEM([]byte(isrgRootX1RootPEM))
|
||||
p.AppendCertsFromPEM([]byte(isrgRootX2RootPEM))
|
||||
r.p = p
|
||||
})
|
||||
}
|
||||
|
||||
// Subject: O = Internet Security Research Group, CN = ISRG Root X1
|
||||
// Key type: RSA 4096
|
||||
// Validity: until 2030-06-04 (generated 2015-06-04)
|
||||
//
|
||||
//go:embed isrg-root-x1.pem
|
||||
var isrgRootX1RootPEM string
|
||||
|
||||
// Subject: O = Internet Security Research Group, CN = ISRG Root X2
|
||||
// Key type: ECDSA P-384
|
||||
// Validity: until 2035-09-04 (generated 2020-09-04)
|
||||
//
|
||||
//go:embed isrg-root-x2.pem
|
||||
var isrgRootX2RootPEM string
|
31
util/embeddedroots/isrg-root-x1.pem
Normal file
31
util/embeddedroots/isrg-root-x1.pem
Normal file
@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
||||
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
||||
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
||||
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
||||
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
||||
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
||||
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
||||
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
||||
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
||||
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
||||
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
||||
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
||||
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
||||
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
||||
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
||||
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
||||
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
||||
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
||||
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
||||
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
||||
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
||||
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
||||
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
||||
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
||||
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
||||
-----END CERTIFICATE-----
|
14
util/embeddedroots/isrg-root-x2.pem
Normal file
14
util/embeddedroots/isrg-root-x2.pem
Normal file
@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
|
||||
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
|
||||
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
|
||||
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
|
||||
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
|
||||
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
|
||||
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
|
||||
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
|
||||
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
|
||||
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
|
||||
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
|
||||
/q4AaOeMSQ+2b1tbFfLn
|
||||
-----END CERTIFICATE-----
|
@ -3,14 +3,16 @@ package grpc
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"net"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
@ -18,6 +20,7 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
|
||||
"github.com/netbirdio/netbird/util/embeddedroots"
|
||||
nbnet "github.com/netbirdio/netbird/util/net"
|
||||
)
|
||||
|
||||
@ -57,9 +60,16 @@ func Backoff(ctx context.Context) backoff.BackOff {
|
||||
|
||||
func CreateConnection(addr string, tlsEnabled bool) (*grpc.ClientConn, error) {
|
||||
transportOption := grpc.WithTransportCredentials(insecure.NewCredentials())
|
||||
|
||||
if tlsEnabled {
|
||||
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil || certPool == nil {
|
||||
log.Debugf("System cert pool not available; falling back to embedded cert, error: %v", err)
|
||||
certPool = embeddedroots.Get()
|
||||
}
|
||||
|
||||
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
|
||||
RootCAs: certPool,
|
||||
}))
|
||||
}
|
||||
|
||||
connCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
|
Loading…
Reference in New Issue
Block a user