feat(influxdb): Add proxy path to cli

pull/16599/head
Brandon Farmer 2020-01-21 10:23:46 -08:00
parent 3cf826f1cf
commit fe517fd9ce
8 changed files with 77 additions and 62 deletions

View File

@ -31,6 +31,7 @@ const (
// DefaultTimeout is the default connection timeout used to connect to an InfluxDB instance
DefaultTimeout = 0
DefaultPath = ""
)
// Query is used to send a command to the server. Both Command and Database are required.
@ -64,23 +65,36 @@ type Query struct {
NodeID int
}
func splitPath(v string) (string, string) {
parts := strings.Split(v, "/")
first := parts[0]
last := strings.Join(parts[1:], "/")
return first, last
}
// ParseConnectionString will parse a string to create a valid connection URL
func ParseConnectionString(path string, ssl bool) (url.URL, error) {
var host string
var port int
var pth string = ""
h, p, err := net.SplitHostPort(path)
if err != nil {
if path == "" {
host = DefaultHost
} else {
host = path
host, pth = splitPath(path)
}
// If they didn't specify a port, always use the default port
port = DefaultPort
} else {
host = h
port, err = strconv.Atoi(p)
prt, pt := splitPath(p)
pth = pt
port, err = strconv.Atoi(prt)
if err != nil {
return url.URL{}, fmt.Errorf("invalid port number %q: %s\n", path, err)
}
@ -89,6 +103,7 @@ func ParseConnectionString(path string, ssl bool) (url.URL, error) {
u := url.URL{
Scheme: "http",
Host: host,
Path: pth,
}
if ssl {
u.Scheme = "https"

View File

@ -815,6 +815,10 @@ func TestClient_ParseConnectionString(t *testing.T) {
addr: "localhost:443",
exp: "http://localhost:443",
},
{
addr: "192.168.2.13:8086/boom",
exp: "http://192.168.2.13:8086/boom",
},
} {
name := tt.addr
if tt.ssl {

View File

@ -10,8 +10,8 @@ import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"os/signal"
"path/filepath"
@ -26,7 +26,7 @@ import (
"golang.org/x/crypto/ssh/terminal"
"github.com/influxdata/influxdb/client"
"github.com/influxdata/influxdb/importer/v8"
v8 "github.com/influxdata/influxdb/importer/v8"
"github.com/influxdata/influxdb/models"
"github.com/influxdata/influxql"
"github.com/peterh/liner"
@ -38,8 +38,10 @@ var ErrBlankCommand = errors.New("empty input")
// CommandLine holds CLI configuration and state.
type CommandLine struct {
Line *liner.State
URL url.URL
Host string
Port int
Path string
Database string
Type QueryLanguage
Ssl bool
@ -114,6 +116,14 @@ func (c *CommandLine) Run() error {
c.ClientConfig.Password = os.Getenv("INFLUX_PASSWORD")
}
addr := fmt.Sprintf("%s:%d/%s", c.Host, c.Port, c.Path)
url, err := client.ParseConnectionString(addr, c.Ssl)
if err != nil {
return err
}
c.URL = url
if err := c.Connect(""); err != nil {
msg := "Please check your connection settings and ensure 'influxd' is running."
if !c.Ssl && strings.Contains(err.Error(), "malformed HTTP response") {
@ -158,17 +168,11 @@ func (c *CommandLine) Run() error {
}
if c.Import {
addr := net.JoinHostPort(c.Host, strconv.Itoa(c.Port))
u, e := client.ParseConnectionString(addr, c.Ssl)
if e != nil {
return e
}
// Copy the latest importer config and inject the latest client config
// into it.
config := c.ImporterConfig
config.Config = c.ClientConfig
config.URL = u
config.URL = c.URL
i := v8.NewImporter(config)
if err := i.Import(); err != nil {
@ -207,7 +211,7 @@ func (c *CommandLine) Run() error {
c.Version()
if c.Type == QueryLanguageFlux {
repl, err := getFluxREPL(c.Host, c.Port, c.Ssl, c.ClientConfig.Username, c.ClientConfig.Password)
repl, err := getFluxREPL(c.URL, c.ClientConfig.Username, c.ClientConfig.Password)
if err != nil {
return err
}
@ -339,11 +343,19 @@ func (c *CommandLine) Connect(cmd string) error {
// normalize cmd
cmd = strings.ToLower(cmd)
ClientConfig := c.ClientConfig
// Remove the "connect" keyword if it exists
addr := strings.TrimSpace(strings.Replace(cmd, "connect", "", -1))
if addr == "" {
// If they didn't provide a connection string, use the current settings
addr = net.JoinHostPort(c.Host, strconv.Itoa(c.Port))
ClientConfig.URL = c.URL
} else {
url, err := client.ParseConnectionString(addr, c.Ssl)
if err != nil {
return err
}
ClientConfig.URL = url
}
URL, err := client.ParseConnectionString(addr, c.Ssl)
@ -351,8 +363,6 @@ func (c *CommandLine) Connect(cmd string) error {
return err
}
// Create copy of the current client config and create a new client.
ClientConfig := c.ClientConfig
ClientConfig.UserAgent = "InfluxDBShell/" + c.ClientVersion
ClientConfig.URL = URL
ClientConfig.Proxy = http.ProxyFromEnvironment
@ -370,12 +380,7 @@ func (c *CommandLine) Connect(cmd string) error {
c.ServerVersion = v
// Update the command with the current connection information
if host, port, err := net.SplitHostPort(ClientConfig.URL.Host); err == nil {
c.Host = host
if i, err := strconv.Atoi(port); err == nil {
c.Port = i
}
}
c.URL = ClientConfig.URL
return nil
}
@ -1042,11 +1047,7 @@ func (c *CommandLine) Settings() {
w.Init(os.Stdout, 0, 1, 1, ' ', 0)
fmt.Fprintln(w, "Setting\tValue")
fmt.Fprintln(w, "--------\t--------")
if c.Port > 0 {
fmt.Fprintf(w, "Host\t%s:%d\n", c.Host, c.Port)
} else {
fmt.Fprintf(w, "Host\t%s\n", c.Host)
}
fmt.Fprintf(w, "URL\t%s\n", c.URL.String())
fmt.Fprintf(w, "Username\t%s\n", c.ClientConfig.Username)
fmt.Fprintf(w, "Database\t%s\n", c.Database)
fmt.Fprintf(w, "RetentionPolicy\t%s\n", c.RetentionPolicy)
@ -1188,7 +1189,7 @@ func (c *CommandLine) ExecuteFluxQuery(query string) error {
}()
}
repl, err := getFluxREPL(c.Host, c.Port, c.Ssl, c.ClientConfig.Username, c.ClientConfig.Password)
repl, err := getFluxREPL(c.URL, c.ClientConfig.Username, c.ClientConfig.Password)
if err != nil {
return err
}

View File

@ -2,6 +2,7 @@ package cli
import (
"context"
"net/url"
"github.com/influxdata/flux"
"github.com/influxdata/flux/csv"
@ -30,8 +31,8 @@ func (q *replQuerier) Query(ctx context.Context, deps flux.Dependencies, compile
return q.client.Query(ctx, req)
}
func getFluxREPL(host string, port int, ssl bool, username, password string) (*repl.REPL, error) {
c, err := client.NewHTTP(host, port, ssl)
func getFluxREPL(u url.URL, username, password string) (*repl.REPL, error) {
c, err := client.NewHTTP(u)
if err != nil {
return nil, err
}

View File

@ -40,6 +40,7 @@ func main() {
fs := flag.NewFlagSet("InfluxDB shell version "+version, flag.ExitOnError)
fs.StringVar(&c.Host, "host", client.DefaultHost, "Influxdb host to connect to.")
fs.StringVar(&c.Path, "proxy-path", client.DefaultPath, "Influxdb url path (for running behind proxies)")
fs.IntVar(&c.Port, "port", client.DefaultPort, "Influxdb port to connect to.")
fs.StringVar(&c.ClientConfig.UnixSocket, "socket", "", "Influxdb unix socket to connect to.")
fs.StringVar(&c.ClientConfig.Username, "username", "", "Username to connect to the server.")
@ -64,43 +65,45 @@ func main() {
fs.Usage = func() {
fmt.Println(`Usage of influx:
-version
Display the version and exit.
Display the version and exit.
-proxy-path 'url path'
Path that follows the host and port
-host 'host name'
Host to connect to.
Host to connect to.
-port 'port #'
Port to connect to.
Port to connect to.
-socket 'unix domain socket'
Unix socket to connect to.
Unix socket to connect to.
-database 'database name'
Database to connect to the server.
Database to connect to the server.
-password 'password'
Password to connect to the server. Leaving blank will prompt for password (--password '').
Password to connect to the server. Leaving blank will prompt for password (--password '').
-username 'username'
Username to connect to the server.
Username to connect to the server.
-ssl
Use https for requests.
Use https for requests.
-unsafeSsl
Set this when connecting to the cluster using https and not use SSL verification.
Set this when connecting to the cluster using https and not use SSL verification.
-execute 'command'
Execute command and quit.
Execute command and quit.
-type 'influxql|flux'
Type specifies the query language for executing commands or when invoking the REPL.
Type specifies the query language for executing commands or when invoking the REPL.
-format 'json|csv|column'
Format specifies the format of the server responses: json, csv, or column.
Format specifies the format of the server responses: json, csv, or column.
-precision 'rfc3339|h|m|s|ms|u|ns'
Precision specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns.
Precision specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns.
-consistency 'any|one|quorum|all'
Set write consistency level: any, one, quorum, or all
Set write consistency level: any, one, quorum, or all
-pretty
Turns on pretty print for the json format.
Turns on pretty print for the json format.
-import
Import a previous database export from file
Import a previous database export from file
-pps
How many points per second the import will allow. By default it is zero and will not throttle importing.
How many points per second the import will allow. By default it is zero and will not throttle importing.
-path
Path to file to import
Path to file to import
-compressed
Set to true if the import file is compressed
Set to true if the import file is compressed
Examples:

View File

@ -8,16 +8,13 @@ import (
"fmt"
"io/ioutil"
"mime"
"net"
"net/http"
"net/url"
"strconv"
"github.com/influxdata/flux"
"github.com/influxdata/flux/csv"
"github.com/influxdata/flux/lang"
"github.com/influxdata/flux/repl"
iclient "github.com/influxdata/influxdb/client"
"github.com/pkg/errors"
)
@ -44,13 +41,7 @@ type HTTP struct {
}
// NewHTTP creates a HTTP client
func NewHTTP(host string, port int, ssl bool) (*HTTP, error) {
addr := net.JoinHostPort(host, strconv.Itoa(port))
u, e := iclient.ParseConnectionString(addr, ssl)
if e != nil {
return nil, e
}
u.Path = fluxPath
func NewHTTP(u url.URL) (*HTTP, error) {
return &HTTP{url: &u}, nil
}

View File

@ -15,7 +15,7 @@ func TestCMO(t *testing.T) {
}
}
if diff := diffFloats(expList, actList, 1E-7); diff != "" {
if diff := diffFloats(expList, actList, 1e-7); diff != "" {
t.Errorf("unexpected floats:\n%s", diff)
}
}
@ -35,7 +35,7 @@ func TestCMOS(t *testing.T) {
}
}
if diff := diffFloats(expList, actList, 1E-7); diff != "" {
if diff := diffFloats(expList, actList, 1e-7); diff != "" {
t.Errorf("unexpected floats:\n%s", diff)
}
}

View File

@ -17,7 +17,7 @@ func TestTRIX(t *testing.T) {
}
}
if diff := diffFloats(expList, actList, 1E-7); diff != "" {
if diff := diffFloats(expList, actList, 1e-7); diff != "" {
t.Errorf("unexpected floats:\n%s", diff)
}
}