Skip to content

Commit

Permalink
Merge pull request #916 from mysteriumnetwork/feature/794-nat-status-cli
Browse files Browse the repository at this point in the history
Add CLI command for retrieving NAT status
  • Loading branch information
donce authored Apr 26, 2019
2 parents 0184237 + c165183 commit 38a630d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 9 deletions.
34 changes: 25 additions & 9 deletions cmd/commands/cli/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func (c *cliApp) handleActions(line string) {
{"help", c.help},
{"status", c.status},
{"healthcheck", c.healthcheck},
{"nat", c.natStatus},
{"ip", c.ip},
{"disconnect", c.disconnect},
{"stop", c.stopClient},
Expand All @@ -153,15 +154,15 @@ func (c *cliApp) handleActions(line string) {
command string
handler func(argsString string)
}{
{command: "connect", handler: c.connect},
{command: "unlock", handler: c.unlock},
{command: "identities", handler: c.identities},
{command: "payout", handler: c.payout},
{command: "version", handler: c.version},
{command: "license", handler: c.license},
{command: "registration", handler: c.registration},
{command: "proposals", handler: c.proposals},
{command: "service", handler: c.service},
{"connect", c.connect},
{"unlock", c.unlock},
{"identities", c.identities},
{"payout", c.payout},
{"version", c.version},
{"license", c.license},
{"registration", c.registration},
{"proposals", c.proposals},
{"service", c.service},
}

for _, cmd := range staticCmds {
Expand Down Expand Up @@ -449,6 +450,20 @@ func (c *cliApp) healthcheck() {
info(buildString)
}

func (c *cliApp) natStatus() {
status, err := c.tequilapi.NATStatus()
if err != nil {
warn("Failed to retrieve NAT traversal status:", err)
return
}

if status.Error == "" {
infof("NAT traversal status: %q\n", status.Status)
} else {
infof("NAT traversal status: %q (error: %q)\n", status.Status, status.Error)
}
}

func (c *cliApp) proposals(filter string) {
proposals := c.fetchProposals()
c.fetchedProposals = proposals
Expand Down Expand Up @@ -673,6 +688,7 @@ func newAutocompleter(tequilapi *tequilapi_client.Client, proposals []tequilapi_
),
readline.PcItem("status"),
readline.PcItem("healthcheck"),
readline.PcItem("nat"),
readline.PcItem("proposals"),
readline.PcItem("ip"),
readline.PcItem("disconnect"),
Expand Down
13 changes: 13 additions & 0 deletions tequilapi/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,19 @@ func (client *Client) ServiceStop(id string) error {
return nil
}

// NATStatus returns status of NAT traversal
func (client *Client) NATStatus() (NATStatusDTO, error) {
status := NATStatusDTO{}

response, err := client.http.Get("nat/status", nil)
if err != nil {
return status, err
}

err = parseResponseJSON(response, &status)
return status, err
}

// ServiceSessions returns all currently running sessions
func (client *Client) ServiceSessions() (ServiceSessionListDTO, error) {
sessions := ServiceSessionListDTO{}
Expand Down
42 changes: 42 additions & 0 deletions tequilapi/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"

Expand All @@ -33,6 +34,37 @@ const errorMessage = `
}
`

func Test_NATStatus_ReturnsStatus(t *testing.T) {
httpClient := mockHTTPClient(
t,
http.MethodGet,
"/nat/status",
http.StatusOK,
`{"status": "failure", "error": "mock error"}`,
)
client := Client{http: httpClient}

status, err := client.NATStatus()

assert.NoError(t, err)
assert.Equal(t, "failure", status.Status)
assert.Equal(t, "mock error", status.Error)
}

func Test_NATStatus_ReturnsError(t *testing.T) {
httpClient := mockHTTPClient(
t,
http.MethodGet,
"/nat/status",
http.StatusInternalServerError,
``,
)
client := Client{http: httpClient}

_, err := client.NATStatus()
assert.Error(t, err)
}

func TestConnectionErrorIsReturnedByClientInsteadOfDoubleParsing(t *testing.T) {
responseBody := &trackingCloser{
Reader: strings.NewReader(errorMessage),
Expand All @@ -58,6 +90,16 @@ func TestConnectionErrorIsReturnedByClientInsteadOfDoubleParsing(t *testing.T) {
assert.True(t, responseBody.Closed)
}

func mockHTTPClient(t *testing.T, method, url string, statusCode int, response string) httpClientInterface {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, method, r.Method)
assert.Equal(t, url, r.URL.Path)
w.Write([]byte(response))
w.WriteHeader(statusCode)
}))
return newHTTPClient(server.URL, "", "")
}

type requestDoer func(req *http.Request) (*http.Response, error)

func (f requestDoer) Do(req *http.Request) (*http.Response, error) {
Expand Down
6 changes: 6 additions & 0 deletions tequilapi/client/dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,9 @@ type ServiceSessionDTO struct {
type AccessPoliciesRequest struct {
IDs []string `json:"ids"`
}

// NATStatusDTO gives information about NAT traversal success or failure
type NATStatusDTO struct {
Status string `json:"status"`
Error string `json:"error,omitempty"`
}

0 comments on commit 38a630d

Please sign in to comment.