diff --git a/api/rest/client/client.go b/api/rest/client/client.go index 1df4d44d..4fdb2c1b 100644 --- a/api/rest/client/client.go +++ b/api/rest/client/client.go @@ -178,7 +178,7 @@ func (c *Config) AsTemplateFor(resolvedAddrs []ma.Multiaddr) ([]*Config) { // AsTemplateForResolvedAddress creates client configs from a multiaddress func (c *Config) AsTemplateForResolvedAddress(addr ma.Multiaddr) ([]*Config, error) { - resolvedAddrs, err := resolveDNSAddr(addr) + resolvedAddrs, err := resolveAddr(context.Background(), addr) if err != nil { return []*Config{}, err } @@ -282,17 +282,10 @@ func (c *defaultClient) resolveAPIAddr() error { if !IsPeerAddress(c.config.APIAddr) { return nil } - resolveCtx, cancel := context.WithTimeout(c.ctx, ResolveTimeout) - defer cancel() - resolved, err := madns.Resolve(resolveCtx, c.config.APIAddr) + resolved, err := resolveAddr(c.ctx, c.config.APIAddr) if err != nil { return err } - - if len(resolved) == 0 { - return fmt.Errorf("resolving %s returned 0 results", c.config.APIAddr) - } - c.config.APIAddr = resolved[0] return nil } @@ -387,44 +380,18 @@ func isUnixSocketAddress(addr ma.Multiaddr) bool { return (value != "" && err == nil) } -// isDNSAddress returns if the given address corresponds to a -// DNSADDR protocol type -func isDNSAddress(addr ma.Multiaddr) bool { - if addr == nil { - return false +// resolve addr +func resolveAddr(ctx context.Context, addr ma.Multiaddr) ([]ma.Multiaddr, error) { + resolveCtx, cancel := context.WithTimeout(ctx, ResolveTimeout) + defer cancel() + resolved, err := madns.Resolve(resolveCtx, addr) + if err != nil { + return []ma.Multiaddr{}, err } - dnsaddr, err := addr.ValueForProtocol(ma.P_DNSADDR) - return (dnsaddr != "" && err == nil) -} - -// resolve dnsaddr -func resolveDNSAddr(addr ma.Multiaddr) ([]ma.Multiaddr, error) { - var prevResolved []ma.Multiaddr - var currResolved []ma.Multiaddr - - // Only resolve dnsaddr - if !isDNSAddress(addr) { - // return the addr as the entry to be resolved later - currResolved = append(currResolved, addr) - return currResolved, nil - } - - // recursively resolve - currResolved = append(currResolved, addr) - for len(currResolved) != len(prevResolved) { - var tobeResolved []ma.Multiaddr - for _, addr := range currResolved { - resolveCtx, cancel := context.WithTimeout(context.Background(), ResolveTimeout) - defer cancel() - resolved, err := madns.Resolve(resolveCtx, addr) - if err != nil { - return []ma.Multiaddr{}, err - } - tobeResolved = append(tobeResolved, resolved...) - } - prevResolved = currResolved - currResolved = tobeResolved - } - - return prevResolved, nil + + if len(resolved) == 0 { + return []ma.Multiaddr{}, fmt.Errorf("resolving %s returned 0 results", addr) + } + + return resolved, nil } diff --git a/cmd/ipfs-cluster-ctl/main.go b/cmd/ipfs-cluster-ctl/main.go index 0a1bb602..5fe4f3d9 100644 --- a/cmd/ipfs-cluster-ctl/main.go +++ b/cmd/ipfs-cluster-ctl/main.go @@ -35,7 +35,6 @@ var ( defaultTimeout = 0 defaultWaitCheckFreq = time.Second defaultAddParams = api.DefaultAddParams() - defaultRetries = 6 ) var logger = logging.Logger("cluster-ctl") @@ -90,10 +89,10 @@ func main() { app.Description = Description app.Version = Version app.Flags = []cli.Flag{ - cli.StringFlag{ + cli.StringSliceFlag{ Name: "host, l", - Value: defaultHost, - Usage: "Cluster's HTTP or LibP2P-HTTP API endpoint", + Value: &cli.StringSlice{defaultHost}, + Usage: "Cluster's HTTP or LibP2P-HTTP API endpoint. To provide multiple hosts: --host a --host b", }, cli.StringFlag{ Name: "secret", @@ -132,11 +131,6 @@ requires authorization. implies --https, which you can disable with --force-http Name: "force-http, f", Usage: "force HTTP. only valid when using BasicAuth", }, - cli.IntFlag{ - Name: "retries, ret", - Value: defaultRetries, - Usage: "number of retries to try until failure", - }, } app.Before = func(c *cli.Context) error { @@ -149,9 +143,6 @@ requires authorization. implies --https, which you can disable with --force-http logger.Debug("debug level enabled") } - addr, err := ma.NewMultiaddr(c.String("host")) - checkErr("parsing host multiaddress", err) - if hexSecret := c.String("secret"); hexSecret != "" { secret, err := hex.DecodeString(hexSecret) checkErr("parsing secret", err) @@ -160,10 +151,6 @@ requires authorization. implies --https, which you can disable with --force-http cfg.Timeout = time.Duration(c.Int("timeout")) * time.Second - if client.IsPeerAddress(addr) && c.Bool("https") { - logger.Warn("Using libp2p-http. SSL flags will be ignored") - } - cfg.SSL = c.Bool("https") cfg.NoVerifyCert = c.Bool("no-check-certificate") user, pass := parseCredentials(c.String("basic-auth")) @@ -179,10 +166,26 @@ requires authorization. implies --https, which you can disable with --force-http checkErr("", errors.New("unsupported encoding")) } - cfgs, err := cfg.AsTemplateForResolvedAddress(addr) - checkErr("creating configs", err) + var configs []*client.Config + var err error + for _, addr := range c.StringSlice("host") { + multiaddr, err := ma.NewMultiaddr(addr) + checkErr("parsing host multiaddress", err) - globalClient, err = client.NewLBClient(&client.Failover{}, cfgs, 6) + cfgs, err := cfg.AsTemplateForResolvedAddress(multiaddr) + checkErr("creating configs", err) + configs = append(configs, cfgs...) + } + + for _, cfg := range configs { + if client.IsPeerAddress(cfg.APIAddr) && c.Bool("https") { + logger.Warn("Using libp2p-http. SSL flags will be ignored") + break; + } + } + + retries := len(configs) + globalClient, err = client.NewLBClient(&client.Failover{}, configs, retries) checkErr("creating API client", err) // TODO: need to figure out best way to configure tracing for ctl