Skip to content

Commit

Permalink
Merge pull request #25 from celestiaorg/mojtaba/go-sdk
Browse files Browse the repository at this point in the history
feat: add a simple sdk for golang
  • Loading branch information
MSevey authored Dec 4, 2023
2 parents 8cef6b8 + 133cae5 commit 8162ce8
Show file tree
Hide file tree
Showing 5 changed files with 665 additions and 0 deletions.
87 changes: 87 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,83 @@ sudo ./bin/bittwister start -d eth0 -l 100
sudo ./bin/bittwister start -d eth0 -j 10
```

### Start the API server

```bash
sudo ./bin/bittwister serve [flags]

Flags:
-h, --help help for serve
--log-level string log level (e.g. debug, info, warn, error, dpanic, panic, fatal) (default "info")
--origin-allowed string origin allowed for CORS (default "*")
--production-mode production mode (e.g. disable debug logs)
--serve-addr string address to serve on (default "localhost:9007")
```

### API Endpoints

Please note that all the endpoints have to be prefixed with `/api/v1`.

#### Packet Loss

- **Endpoint:** `/packetloss`
- `/start`
- **Method:** POST
- **Data**: `{"network_interface":"eth0","packet_loss_rate":30}`
- **Description:** Start packetloss service.
- `/status`
- **Method:** GET
- **Description:** Get packetloss status.
- `/stop`
- **Method:** POST
- **Description:** Stop packetloss service.

**example:**

```bash
curl -iX POST http://localhost:9007/api/v1/packetloss/start --data '{"network_interface":"eth0","packet_loss_rate":30}'
```

#### Bandwidth

- **Endpoint:** `/bandwidth`
- `/start`
- **Method:** POST
- **Data**: `{"network_interface":"eth0","bandwidth":1048576}`
- **Description:** Start bandwidth service.
- `/status`
- **Method:** GET
- **Description:** Get bandwidth status.
- `/stop`
- **Method:** POST
- **Description:** Stop bandwidth service.

#### Latency

- **Endpoint:** `/latency`
- `/start`
- **Method:** POST
- **Data**: `{"network_interface":"eth0","latency":100,"jitter":10}`
- **Description:** Start latency service.
- `/status`
- **Method:** GET
- **Description:** Get latency status.
- `/stop`
- **Method:** POST
- **Description:** Stop latency service.

#### Services

- **Endpoint:** `/services`
- `/status`
- **Method:** GET
- **Description:** Get all network restriction services statuses and their configured parameters.

### SDK for Go

The BitTwister SDK for Go provides a convenient interface to interact with the BitTwister tool, which applies network restrictions on a network interface, including bandwidth limitation, packet loss, latency, and jitter.
More details about the SDK and how to use it can be found [here](./sdk/README.md).

### Using Bittwister in Kubernetes

To utilize Bittwister within a Kubernetes environment, specific configurations must be added to the container.
Expand Down Expand Up @@ -75,6 +152,16 @@ The tests require docker to be installed. To run all the tests, execute the foll
make test
```

### Go unit tests

The Go unit tests can be run by executing the following command:

```bash
make test-go
```

**Note**: Root permission is required to run the unit tests. The tests are run on the loopback interface.

### Test Packet Loss

The packet loss function can be tested by running the following command:
Expand Down
70 changes: 70 additions & 0 deletions sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# BitTwister SDK for Go

The BitTwister SDK for Go provides a convenient interface to interact with the BitTwister tool, which applies network restrictions on a network interface, including bandwidth limitation, packet loss, latency, and jitter.

## Installation

To use this SDK, import it into your Go project:

```bash
go get -u github.com/celestiaorg/bittwister/sdk
```

## Usage

### Initialization

First, import the SDK into your Go project:

```go
import "github.com/celestiaorg/bittwister/sdk"
```

Next, create a client by specifying the base URL of where BitTwister is running e.g. _a container running on the same machine_:

```go
func main() {
baseURL := "http://localhost:9007/api/v1"
client := sdk.NewClient(baseURL)
// Use the client for API requests
}
```

### Examples

Bandwidth Service

Start the Bandwidth service with a specified network interface and bandwidth limit:

```go
req := sdk.BandwidthStartRequest{
NetworkInterfaceName: "eth0",
Limit: 100,
}

err := client.BandwidthStart(req)
if err != nil {
// Handle error
}
```

Stop the Bandwidth service:

```go
err := client.BandwidthStop()
if err != nil {
// Handle error
}
```

Retrieve the status of the Bandwidth service:

```go
status, err := client.BandwidthStatus()
if err != nil {
// Handle error
}
// Use status for further processing
```

Similarly, you can use PacketlossStart, PacketlossStop, PacketlossStatus, LatencyStart, LatencyStop, LatencyStatus, and other functions provided by the SDK following similar usage patterns.
59 changes: 59 additions & 0 deletions sdk/apis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package sdk

import (
"encoding/json"

"github.com/celestiaorg/bittwister/api/v1"
)

func (c *Client) PacketlossStart(req api.PacketLossStartRequest) error {
_, err := c.postResource("/packetloss/start", req)
return err
}

func (c *Client) PacketlossStop() error {
_, err := c.postResource("/packetloss/stop", nil)
return err
}

func (c *Client) PacketlossStatus() (*api.MetaMessage, error) {
return c.getServiceStatus("/packetloss/status")
}

func (c *Client) BandwidthStart(req api.BandwidthStartRequest) error {
_, err := c.postResource("/bandwidth/start", req)
return err
}

func (c *Client) BandwidthStop() error {
_, err := c.postResource("/bandwidth/stop", nil)
return err
}

func (c *Client) BandwidthStatus() (*api.MetaMessage, error) {
return c.getServiceStatus("/bandwidth/status")
}

func (c *Client) LatencyStart(req api.LatencyStartRequest) error {
_, err := c.postResource("/latency/start", req)
return err
}

func (c *Client) LatencyStop() error {
_, err := c.postResource("/latency/stop", nil)
return err
}

func (c *Client) LatencyStatus() (*api.MetaMessage, error) {
return c.getServiceStatus("/latency/status")
}

func (c *Client) AllServicesStatus() ([]api.ServiceStatus, error) {
resp, err := c.getResource("/services/status")
msgs := []api.ServiceStatus{}

if err := json.Unmarshal(resp, &msgs); err != nil {
return nil, err
}
return msgs, err
}
82 changes: 82 additions & 0 deletions sdk/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package sdk

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"

"github.com/celestiaorg/bittwister/api/v1"
)

type Client struct {
baseURL string
httpClient *http.Client
}

func NewClient(baseURL string) *Client {
return &Client{
baseURL: baseURL,
httpClient: http.DefaultClient,
}
}

func (c *Client) getResource(resPath string) ([]byte, error) {
resp, err := c.httpClient.Get(c.baseURL + resPath)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
}

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

return body, nil
}

func (c *Client) postResource(resPath string, requestBody interface{}) ([]byte, error) {
requestBodyJSON, err := json.Marshal(requestBody)
if err != nil {
return nil, err
}

req, err := http.NewRequest("POST", c.baseURL+resPath, bytes.NewBuffer(requestBodyJSON))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")

resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
}

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

return body, nil
}

func (c *Client) getServiceStatus(resPath string) (*api.MetaMessage, error) {
resp, err := c.getResource(resPath)
msg := &api.MetaMessage{}

if err := json.Unmarshal(resp, msg); err != nil {
return nil, err
}
return msg, err
}
Loading

0 comments on commit 8162ce8

Please sign in to comment.