Skip to content

Commit

Permalink
Update structure
Browse files Browse the repository at this point in the history
  • Loading branch information
arslanbekov committed Jan 11, 2024
1 parent 656ff1e commit f993673
Show file tree
Hide file tree
Showing 14 changed files with 481 additions and 289 deletions.
69 changes: 54 additions & 15 deletions cloudconnexa/cloudconnexa.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,106 @@ import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
"time"

"golang.org/x/time/rate"
)

const (
userAgent = "cloudconnexa-go"
)

type Client struct {
HTTPClient *http.Client
client *http.Client

BaseURL string
Token string
RateLimiter *rate.Limiter

UserAgent string

common service

Connectors *ConnectorsService
DnsRecords *DNSRecordsService
Hosts *HostsService
IPServices *IPServicesService
Networks *NetworksService
Routes *RoutesService
Users *UsersService
UserGroups *UserGroupsService
VPNRegions *VPNRegionsService
}

type service struct {
client *Client
}

type Credentials struct {
AccessToken string `json:"access_token"`
}

func NewClient(baseUrl, clientId, clientSecret string) (*Client, error) {
func NewClient(baseURL, clientId, clientSecret string) (*Client, error) {
if clientId == "" || clientSecret == "" {
return nil, ErrCredentialsRequired
}

values := map[string]string{"grant_type": "client_credentials", "scope": "default"}
json_data, err := json.Marshal(values)
jsonData, err := json.Marshal(values)
if err != nil {
return nil, err
}

req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/beta/oauth/token", baseUrl), bytes.NewBuffer(json_data))
tokenURL := fmt.Sprintf("%s/api/beta/oauth/token", strings.TrimRight(baseURL, "/"))
req, err := http.NewRequest(http.MethodPost, tokenURL, bytes.NewBuffer(jsonData))

if err != nil {
return nil, err
}

req.SetBasicAuth(clientId, clientSecret)
req.Header.Add("Accept", "application/json")
httpClient := http.DefaultClient
httpClient := &http.Client{Timeout: 30 * time.Second}
resp, err := httpClient.Do(req)

if err != nil {
return nil, err
}

defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

defer resp.Body.Close()
log.Printf("NewClient: response body: %s\n", string(body))

var credentials Credentials
err = json.Unmarshal(body, &credentials)
if err != nil {
return nil, err
}

return &Client{
HTTPClient: &http.Client{
Timeout: 30 * time.Second,
},
BaseURL: baseUrl,
c := &Client{
client: httpClient,
BaseURL: baseURL,
Token: credentials.AccessToken,
UserAgent: userAgent,
RateLimiter: rate.NewLimiter(rate.Every(1*time.Second), 5),
}, nil
}
c.common.client = c
c.Connectors = (*ConnectorsService)(&c.common)
c.DnsRecords = (*DNSRecordsService)(&c.common)
c.Hosts = (*HostsService)(&c.common)
c.IPServices = (*IPServicesService)(&c.common)
c.Networks = (*NetworksService)(&c.common)
c.Routes = (*RoutesService)(&c.common)
c.Users = (*UsersService)(&c.common)
c.UserGroups = (*UserGroupsService)(&c.common)
c.VPNRegions = (*VPNRegionsService)(&c.common)
return c, nil
}

func (c *Client) DoRequest(req *http.Request) ([]byte, error) {
Expand All @@ -77,7 +116,7 @@ func (c *Client) DoRequest(req *http.Request) ([]byte, error) {

req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Token))

res, err := c.HTTPClient.Do(req)
res, err := c.client.Do(req)
if err != nil {
return nil, err
}
Expand All @@ -89,7 +128,7 @@ func (c *Client) DoRequest(req *http.Request) ([]byte, error) {
}

if res.StatusCode < 200 || res.StatusCode >= 300 {
return nil, fmt.Errorf("Status code: %d, Response body: %s", res.StatusCode, string(body))
return nil, fmt.Errorf("status code: %d, response body: %s", res.StatusCode, string(body))
}

return body, nil
Expand Down
107 changes: 107 additions & 0 deletions cloudconnexa/cloudconnexa_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package cloudconnexa

import (
"encoding/json"
"github.com/stretchr/testify/assert"
"golang.org/x/time/rate"
"log"
"net/http"
"net/http/httptest"
"testing"
)

func setupMockServer() *httptest.Server {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/beta/oauth/token":
if r.Method == "POST" {
log.Println("Mock server: received POST request for token")
w.Header().Set("Content-Type", "application/json")
response := Credentials{AccessToken: "mocked-token"}
err := json.NewEncoder(w).Encode(response)
if err != nil {
log.Printf("Mock server: error encoding response: %v\n", err)
}
} else {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
case "/valid-endpoint":
if r.Method == "GET" {
w.Header().Set("Content-Type", "application/json")
} else {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
default:
http.Error(w, "Not Found", http.StatusNotFound)
}
}))

return server
}

func TestNewClient(t *testing.T) {
server := setupMockServer()
defer server.Close()

tests := []struct {
name string
baseURL string
clientId string
clientSecret string
wantErr bool
}{
{"Valid Credentials", server.URL, "test-id", "test-secret", false},
{"Empty ClientId", server.URL, "", "test-secret", true},
{"Empty ClientSecret", server.URL, "test-id", "", true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := NewClient(tt.baseURL, tt.clientId, tt.clientSecret)

if tt.wantErr {
assert.Error(t, err, "NewClient should return an error for invalid credentials")
} else {
assert.NoError(t, err, "NewClient should not return an error for valid credentials")
assert.NotNil(t, client, "Client should not be nil for valid credentials")
}
})
}
}

func TestDoRequest(t *testing.T) {
server := setupMockServer()
defer server.Close()

client := &Client{
client: server.Client(),
BaseURL: server.URL,
Token: "mock-access-token",
RateLimiter: rate.NewLimiter(rate.Every(1), 5),
}

tests := []struct {
name string
method string
endpoint string
wantError bool
}{
{"Valid Request", "GET", "/valid-endpoint", false},
{"Invalid Endpoint", "GET", "/invalid-endpoint", true},
{"Invalid Method", "POST", "/valid-endpoint", true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req, _ := http.NewRequest(tt.method, client.BaseURL+tt.endpoint, nil)
resp, err := client.DoRequest(req)

if tt.wantError {
assert.Error(t, err, "DoRequest should return an error")
} else {
assert.NoError(t, err, "DoRequest should not return an error")
assert.NotNil(t, resp, "Response should not be nil for valid requests")
}
})
}
}
52 changes: 22 additions & 30 deletions cloudconnexa/connector.go → cloudconnexa/connectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,16 @@ type ConnectorPageResponse struct {
TotalPages int `json:"totalPages"`
}

const (
NetworkItemTypeHost = "HOST"
NetworkItemTypeNetwork = "NETWORK"
)

const (
ConnectionStatusOffline ConnectionStatus = "OFFLINE"
ConnectionStatusOnline ConnectionStatus = "ONLINE"
)
type ConnectorsService service

func (c *Client) GetConnectorsByPage(page int, pageSize int) (ConnectorPageResponse, error) {
endpoint := fmt.Sprintf("%s/api/beta/connectors/page?page=%d&size=%d", c.BaseURL, page, pageSize)
func (c *ConnectorsService) GetByPage(page int, pageSize int) (ConnectorPageResponse, error) {
endpoint := fmt.Sprintf("%s/api/beta/connectors/page?page=%d&size=%d", c.client.BaseURL, page, pageSize)
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
return ConnectorPageResponse{}, err
}

body, err := c.DoRequest(req)
body, err := c.client.DoRequest(req)
if err != nil {
return ConnectorPageResponse{}, err
}
Expand All @@ -61,13 +53,13 @@ func (c *Client) GetConnectorsByPage(page int, pageSize int) (ConnectorPageRespo
return response, nil
}

func (c *Client) GetAllConnectors() ([]Connector, error) {
func (c *ConnectorsService) GetAll() ([]Connector, error) {
var allConnectors []Connector
page := 1
pageSize := 10

for {
response, err := c.GetConnectorsByPage(page, pageSize)
response, err := c.GetByPage(page, pageSize)
if err != nil {
return nil, err
}
Expand All @@ -82,8 +74,8 @@ func (c *Client) GetAllConnectors() ([]Connector, error) {
return allConnectors, nil
}

func (c *Client) GetConnectorByName(name string) (*Connector, error) {
connectors, err := c.GetAllConnectors()
func (c *ConnectorsService) GetByName(name string) (*Connector, error) {
connectors, err := c.GetAll()
if err != nil {
return nil, err
}
Expand All @@ -96,22 +88,22 @@ func (c *Client) GetConnectorByName(name string) (*Connector, error) {
return nil, nil
}

func (c *Client) GetConnectorById(connectorId string) (*Connector, error) {
connectors, err := c.GetAllConnectors()
func (c *ConnectorsService) GetByID(connectorID string) (*Connector, error) {
connectors, err := c.GetAll()
if err != nil {
return nil, err
}

for _, connector := range connectors {
if connector.Id == connectorId {
if connector.Id == connectorID {
return &connector, nil
}
}
return nil, nil
}

func (c *Client) GetConnectorsForNetwork(networkId string) ([]Connector, error) {
connectors, err := c.GetAllConnectors()
func (c *ConnectorsService) GetByNetworkID(networkId string) ([]Connector, error) {
connectors, err := c.GetAll()
if err != nil {
return nil, err
}
Expand All @@ -125,31 +117,31 @@ func (c *Client) GetConnectorsForNetwork(networkId string) ([]Connector, error)
return networkConnectors, nil
}

func (c *Client) GetConnectorProfile(id string) (string, error) {
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/beta/connectors/%s/profile", c.BaseURL, id), nil)
func (c *ConnectorsService) GetProfile(id string) (string, error) {
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/beta/connectors/%s/profile", c.client.BaseURL, id), nil)
if err != nil {
return "", err
}

body, err := c.DoRequest(req)
body, err := c.client.DoRequest(req)
if err != nil {
return "", err
}
return string(body), nil
}

func (c *Client) CreateConnector(connector Connector, networkItemId string) (*Connector, error) {
func (c *ConnectorsService) Create(connector Connector, networkItemId string) (*Connector, error) {
connectorJson, err := json.Marshal(connector)
if err != nil {
return nil, err
}

req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/beta/connectors?networkItemId=%s&networkItemType=%s", c.BaseURL, networkItemId, connector.NetworkItemType), bytes.NewBuffer(connectorJson))
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/beta/connectors?networkItemId=%s&networkItemType=%s", c.client.BaseURL, networkItemId, connector.NetworkItemType), bytes.NewBuffer(connectorJson))
if err != nil {
return nil, err
}

body, err := c.DoRequest(req)
body, err := c.client.DoRequest(req)
if err != nil {
return nil, err
}
Expand All @@ -162,12 +154,12 @@ func (c *Client) CreateConnector(connector Connector, networkItemId string) (*Co
return &conn, nil
}

func (c *Client) DeleteConnector(connectorId string, networkItemId string, networkItemType string) error {
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/api/beta/connectors/%s?networkItemId=%s&networkItemType=%s", c.BaseURL, connectorId, networkItemId, networkItemType), nil)
func (c *ConnectorsService) Delete(connectorId string, networkItemId string, networkItemType string) error {
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/api/beta/connectors/%s?networkItemId=%s&networkItemType=%s", c.client.BaseURL, connectorId, networkItemId, networkItemType), nil)
if err != nil {
return err
}

_, err = c.DoRequest(req)
_, err = c.client.DoRequest(req)
return err
}
Loading

0 comments on commit f993673

Please sign in to comment.