Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MYST-268 Add endpoint and CLI command for current IP #118

Merged
merged 9 commits into from Jan 26, 2018
83 changes: 52 additions & 31 deletions cmd/mysterium_client/cli/command.go
Expand Up @@ -81,42 +81,55 @@ func (c *Command) Kill() error {

func (c *Command) handleActions(line string) {
line = strings.TrimSpace(line)
switch {
case strings.HasPrefix(line, "connect"):
c.connect(line)
case line == "exit" || line == "quit":
c.quit()

case strings.HasPrefix(line, "unlock"):
c.unlock(line)

case line == "help":
c.help()

case line == "status":
c.status()
staticCmds := []struct {
command string
handler func()
}{
{"exit", c.quit},
{"quit", c.quit},
{"help", c.help},
{"status", c.status},
{"ip", c.ip},
{"disconnect", c.disconnect},
}

case line == "disconnect":
c.disconnect()
argCmds := []struct {
command string
handler func(argsString string)
}{
{command: "connect", handler: c.connect},
{command: "unlock", handler: c.unlock},
{command: "identities", handler: c.identities},
}

case strings.HasPrefix(line, "identities"):
c.identities(line)
for _, cmd := range staticCmds {
if line == cmd.command {
cmd.handler()
return
}
}

default:
if len(line) > 0 {
c.help()
for _, cmd := range argCmds {
if strings.HasPrefix(line, cmd.command) {
argsString := strings.TrimSpace(line[len(cmd.command):])
cmd.handler(argsString)
return
}
}

if len(line) > 0 {
c.help()
}
}

func (c *Command) connect(line string) {
connectionArgs := strings.TrimSpace(line[7:])
if len(connectionArgs) == 0 {
func (c *Command) connect(argsString string) {
if len(argsString) == 0 {
info("Press tab to select identity or create a new one. Connect <your-identity> <node-identity>")
return
}

identities := strings.Fields(connectionArgs)
identities := strings.Fields(argsString)

if len(identities) != 2 {
info("Please type in the node identity. Connect <your-identity> <node-identity>")
Expand Down Expand Up @@ -146,16 +159,14 @@ func (c *Command) connect(line string) {
success("Connected.")
}

func (c *Command) unlock(line string) {
unlockArgs := strings.TrimSpace(line[6:])

func (c *Command) unlock(argsString string) {
unlockSignature := "Unlock <identity> [passphrase]"
if len(unlockArgs) == 0 {
if len(argsString) == 0 {
info("Press tab to select identity.", unlockSignature)
return
}

args := strings.Fields(unlockArgs)
args := strings.Fields(argsString)
var identity, passphrase string

if len(args) == 1 {
Expand Down Expand Up @@ -198,6 +209,16 @@ func (c *Command) status() {
info("SID:", status.SessionId)
}

func (c *Command) ip() {
ip, err := c.tequilapi.GetIP()
if err != nil {
warn(err)
return
}

info("IP:", ip)
}

func (c *Command) help() {
info("Mysterium CLI tequilapi commands:")
fmt.Println(c.completer.Tree(" "))
Expand All @@ -211,8 +232,7 @@ func (c *Command) quit() {
}
}

func (c *Command) identities(line string) {
argsString := strings.TrimSpace(line[10:])
func (c *Command) identities(argsString string) {
const usage = "identities command:\n list\n new [passphrase]"
if len(argsString) == 0 {
info(usage)
Expand Down Expand Up @@ -293,6 +313,7 @@ func newAutocompleter(tequilapi *tequilapi_client.Client) *readline.PrefixComple
readline.PcItem("list"),
),
readline.PcItem("status"),
readline.PcItem("ip"),
readline.PcItem("disconnect"),
readline.PcItem("help"),
readline.PcItem("quit"),
Expand Down
4 changes: 3 additions & 1 deletion cmd/mysterium_client/run/command.go
Expand Up @@ -8,6 +8,7 @@ import (
nats_dialog "github.com/mysterium/node/communication/nats/dialog"
nats_discovery "github.com/mysterium/node/communication/nats/discovery"
"github.com/mysterium/node/identity"
"github.com/mysterium/node/ip"
"github.com/mysterium/node/openvpn"
"github.com/mysterium/node/server"
"github.com/mysterium/node/tequilapi"
Expand Down Expand Up @@ -48,7 +49,8 @@ func NewCommandWith(

router := tequilapi.NewAPIRouter()
tequilapi_endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient, signerFactory)
tequilapi_endpoints.AddRoutesForConnection(router, connectionManager)
ipResolver := ip.NewResolver()
tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver)
tequilapi_endpoints.AddRoutesForProposals(router, mysteriumClient)

httpAPIServer := tequilapi.NewServer(options.TequilapiAddress, options.TequilapiPort, router)
Expand Down
4 changes: 2 additions & 2 deletions cmd/mysterium_fake/mysterium_fake.go
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/mysterium/node/cmd"
command_client "github.com/mysterium/node/cmd/mysterium_client/run"
command_server "github.com/mysterium/node/cmd/mysterium_server/command_run"
"github.com/mysterium/node/ipify"
"github.com/mysterium/node/ip"
"github.com/mysterium/node/nat"
"github.com/mysterium/node/server"
"os"
Expand All @@ -26,7 +26,7 @@ func main() {
DirectoryRuntime: ClientDirectoryRuntime,
},
mysteriumClient,
ipify.NewClientFake(NodeIP),
ip.NewFakeResolver(NodeIP),
nat.NewServiceFake(),
)
cmd.NewTerminator(serverCommand)
Expand Down
12 changes: 6 additions & 6 deletions cmd/mysterium_monitor/command_run/command.go
Expand Up @@ -3,15 +3,15 @@ package command_run
import (
"errors"
command_client "github.com/mysterium/node/cmd/mysterium_client/run"
"github.com/mysterium/node/ipify"
"github.com/mysterium/node/ip"
"github.com/mysterium/node/openvpn"
"sync"
"time"
)

type CommandRun struct {
IpifyClient ipify.Client
ipOriginal string
ipResolver ip.Resolver
ipOriginal string

clientCommand *command_client.CommandRun
ipCheckWaiter sync.WaitGroup
Expand All @@ -33,7 +33,7 @@ func (cmd *CommandRun) Run(options CommandOptions) error {
}
defer nodeProvider.Close()

cmd.ipOriginal, err = cmd.IpifyClient.GetOutboundIP()
cmd.ipOriginal, err = cmd.ipResolver.GetOutboundIP()
if err != nil {
return errors.New("Failed to get original IP: " + err.Error())
}
Expand Down Expand Up @@ -66,7 +66,7 @@ func (cmd *CommandRun) Run(options CommandOptions) error {
// state.NewMiddleware(cmd.checkClientIPWhenConnected)
func (cmd *CommandRun) checkClientIPWhenConnected(state openvpn.State) error {
if state == openvpn.STATE_CONNECTED {
ipForwarded, err := cmd.IpifyClient.GetOutboundIP()
ipForwarded, err := cmd.ipResolver.GetOutboundIP()
if err != nil {
cmd.resultWriter.NodeError("Forwarded IP not detected", err)
cmd.ipCheckWaiter.Done()
Expand All @@ -93,7 +93,7 @@ func (cmd *CommandRun) checkClientHandleTimeout() {
}

func (cmd *CommandRun) checkClientIPWhenDisconnected() {
ipForwarded, err := cmd.IpifyClient.GetOutboundIP()
ipForwarded, err := cmd.ipResolver.GetOutboundIP()
if err != nil {
cmd.resultWriter.NodeError("Disconnect IP not detected", err)
return
Expand Down
4 changes: 2 additions & 2 deletions cmd/mysterium_monitor/command_run/factory.go
Expand Up @@ -2,14 +2,14 @@ package command_run

import (
"github.com/mysterium/node/cmd/mysterium_monitor/command_run/node_provider"
"github.com/mysterium/node/ipify"
"github.com/mysterium/node/ip"
"path/filepath"
"time"
)

func NewCommand() *CommandRun {
return &CommandRun{
IpifyClient: ipify.NewClientWithTimeout(5 * time.Second),
ipResolver: ip.NewResolverWithTimeout(5 * time.Second),
}
}

Expand Down
14 changes: 7 additions & 7 deletions cmd/mysterium_server/command_run/command.go
Expand Up @@ -4,7 +4,7 @@ import (
log "github.com/cihub/seelog"
"github.com/mysterium/node/communication"
"github.com/mysterium/node/identity"
"github.com/mysterium/node/ipify"
"github.com/mysterium/node/ip"
"github.com/mysterium/node/location"
"github.com/mysterium/node/nat"
"github.com/mysterium/node/openvpn"
Expand All @@ -19,7 +19,7 @@ import (
type CommandRun struct {
identityLoader func() (identity.Identity, error)
createSigner identity.SignerFactory
ipifyClient ipify.Client
ipResolver ip.Resolver
mysteriumClient server.Client
natService nat.NATService
locationDetector location.Detector
Expand All @@ -43,7 +43,7 @@ func (cmd *CommandRun) Run() (err error) {
cmd.dialogWaiter, providerContact = cmd.dialogWaiterFactory(providerID)

// if for some reason we will need truly external IP, use GetPublicIP()
vpnServerIP, err := cmd.ipifyClient.GetOutboundIP()
vpnServerIP, err := cmd.ipResolver.GetOutboundIP()
if err != nil {
return err
}
Expand All @@ -56,7 +56,7 @@ func (cmd *CommandRun) Run() (err error) {
return err
}

country, err := detectCountry(cmd.ipifyClient, cmd.locationDetector)
country, err := detectCountry(cmd.ipResolver, cmd.locationDetector)
if err != nil {
return err
}
Expand Down Expand Up @@ -94,13 +94,13 @@ func (cmd *CommandRun) Run() (err error) {
return nil
}

func detectCountry(ipifyClient ipify.Client, detector location.Detector) (string, error) {
ip, err := ipifyClient.GetPublicIP()
func detectCountry(ipResolver ip.Resolver, locationDetector location.Detector) (string, error) {
ip, err := ipResolver.GetPublicIP()
if err != nil {
return "", errors.New("IP detection failed: " + err.Error())
}

country, err := detector.DetectCountry(ip)
country, err := locationDetector.DetectCountry(ip)
if err != nil {
return "", errors.New("Country detection failed: " + err.Error())
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/mysterium_server/command_run/factory.go
Expand Up @@ -7,7 +7,7 @@ import (
nats_dialog "github.com/mysterium/node/communication/nats/dialog"
nats_discovery "github.com/mysterium/node/communication/nats/discovery"
"github.com/mysterium/node/identity"
"github.com/mysterium/node/ipify"
"github.com/mysterium/node/ip"
"github.com/mysterium/node/location"
"github.com/mysterium/node/nat"
"github.com/mysterium/node/openvpn"
Expand All @@ -23,15 +23,15 @@ func NewCommand(options CommandOptions) *CommandRun {
return NewCommandWith(
options,
server.NewClient(),
ipify.NewClient(),
ip.NewResolver(),
nat.NewService(),
)
}

func NewCommandWith(
options CommandOptions,
mysteriumClient server.Client,
ipifyClient ipify.Client,
ipResolver ip.Resolver,
natService nat.NATService,
) *CommandRun {

Expand All @@ -57,7 +57,7 @@ func NewCommandWith(
},
createSigner: createSigner,
locationDetector: locationDetector,
ipifyClient: ipifyClient,
ipResolver: ipResolver,
mysteriumClient: mysteriumClient,
natService: natService,
dialogWaiterFactory: func(myIdentity identity.Identity) (communication.DialogWaiter, dto_discovery.Contact) {
Expand Down
2 changes: 1 addition & 1 deletion ipify/dto.go → ip/dto.go
@@ -1,4 +1,4 @@
package ipify
package ip

type IPResponse struct {
IP string `json:"IP"`
Expand Down
28 changes: 28 additions & 0 deletions ip/fake_resolver.go
@@ -0,0 +1,28 @@
package ip

func NewFakeResolver(ip string) Resolver {
return &fakeResolver{
ip: ip,
error: nil,
}
}

func NewFailingFakeResolver(err error) Resolver {
return &fakeResolver{
ip: "",
error: err,
}
}

type fakeResolver struct {
ip string
error error
}

func (client *fakeResolver) GetPublicIP() (string, error) {
return client.ip, client.error
}

func (client *fakeResolver) GetOutboundIP() (string, error) {
return client.ip, client.error
}
4 changes: 2 additions & 2 deletions ipify/interface.go → ip/resolver.go
@@ -1,6 +1,6 @@
package ipify
package ip

type Client interface {
type Resolver interface {
GetPublicIP() (string, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be 2 implementations with same ip. Resolver interface e.g. NewPublicResolver(), NewOutboundResolver()

GetOutboundIP() (string, error)
}