feat(influxdb): Add proxy path to cli
parent
3cf826f1cf
commit
fe517fd9ce
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue