Release Argo Tunnel Client 2018.4.7
This commit is contained in:
parent
ff6a14283d
commit
77e7c240c0
|
@ -103,7 +103,7 @@ func hello(c *cli.Context) error {
|
|||
}
|
||||
|
||||
func startHelloWorldServer(listener net.Listener, shutdownC <-chan struct{}) error {
|
||||
Log.Infof("Starting Hello World server at %s", listener.Addr())
|
||||
logger.Infof("Starting Hello World server at %s", listener.Addr())
|
||||
serverName := defaultServerName
|
||||
if hostname, err := os.Hostname(); err == nil {
|
||||
serverName = hostname
|
||||
|
|
|
@ -90,8 +90,8 @@ var sysvTemplate = ServiceTemplate{
|
|||
# Short-Description: Argo Tunnel
|
||||
# Description: Argo Tunnel agent
|
||||
### END INIT INFO
|
||||
cmd="{{.Path}} --config /etc/cloudflared/config.yml --origincert /etc/cloudflared/cert.pem --pidfile /var/run/$name.pid --autoupdate-freq 24h0m0s"
|
||||
name=$(basename $(readlink -f $0))
|
||||
cmd="{{.Path}} --config /etc/cloudflared/config.yml --origincert /etc/cloudflared/cert.pem --pidfile /var/run/$name.pid --autoupdate-freq 24h0m0s"
|
||||
pid_file="/var/run/$name.pid"
|
||||
stdout_log="/var/log/$name.log"
|
||||
stderr_log="/var/log/$name.err"
|
||||
|
@ -184,17 +184,17 @@ func installLinuxService(c *cli.Context) error {
|
|||
defaultConfigDir := filepath.Dir(c.String("config"))
|
||||
defaultConfigFile := filepath.Base(c.String("config"))
|
||||
if err = copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile); err != nil {
|
||||
Log.WithError(err).Infof("Failed to copy user configuration. Before running the service, ensure that %s contains two files, %s and %s",
|
||||
logger.WithError(err).Infof("Failed to copy user configuration. Before running the service, ensure that %s contains two files, %s and %s",
|
||||
serviceConfigDir, credentialFile, defaultConfigFiles[0])
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case isSystemd():
|
||||
Log.Infof("Using Systemd")
|
||||
logger.Infof("Using Systemd")
|
||||
return installSystemd(&templateArgs)
|
||||
default:
|
||||
Log.Infof("Using Sysv")
|
||||
logger.Infof("Using Sysv")
|
||||
return installSysv(&templateArgs)
|
||||
}
|
||||
}
|
||||
|
@ -203,30 +203,30 @@ func installSystemd(templateArgs *ServiceTemplateArgs) error {
|
|||
for _, serviceTemplate := range systemdTemplates {
|
||||
err := serviceTemplate.Generate(templateArgs)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error generating service template")
|
||||
logger.WithError(err).Infof("error generating service template")
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := runCommand("systemctl", "enable", "cloudflared.service"); err != nil {
|
||||
Log.WithError(err).Infof("systemctl enable cloudflared.service error")
|
||||
logger.WithError(err).Infof("systemctl enable cloudflared.service error")
|
||||
return err
|
||||
}
|
||||
if err := runCommand("systemctl", "start", "cloudflared-update.timer"); err != nil {
|
||||
Log.WithError(err).Infof("systemctl start cloudflared-update.timer error")
|
||||
logger.WithError(err).Infof("systemctl start cloudflared-update.timer error")
|
||||
return err
|
||||
}
|
||||
Log.Infof("systemctl daemon-reload")
|
||||
logger.Infof("systemctl daemon-reload")
|
||||
return runCommand("systemctl", "daemon-reload")
|
||||
}
|
||||
|
||||
func installSysv(templateArgs *ServiceTemplateArgs) error {
|
||||
confPath, err := sysvTemplate.ResolvePath()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error resolving system path")
|
||||
logger.WithError(err).Infof("error resolving system path")
|
||||
return err
|
||||
}
|
||||
if err := sysvTemplate.Generate(templateArgs); err != nil {
|
||||
Log.WithError(err).Infof("error generating system template")
|
||||
logger.WithError(err).Infof("error generating system template")
|
||||
return err
|
||||
}
|
||||
for _, i := range [...]string{"2", "3", "4", "5"} {
|
||||
|
@ -245,36 +245,36 @@ func installSysv(templateArgs *ServiceTemplateArgs) error {
|
|||
func uninstallLinuxService(c *cli.Context) error {
|
||||
switch {
|
||||
case isSystemd():
|
||||
Log.Infof("Using Systemd")
|
||||
logger.Infof("Using Systemd")
|
||||
return uninstallSystemd()
|
||||
default:
|
||||
Log.Infof("Using Sysv")
|
||||
logger.Infof("Using Sysv")
|
||||
return uninstallSysv()
|
||||
}
|
||||
}
|
||||
|
||||
func uninstallSystemd() error {
|
||||
if err := runCommand("systemctl", "disable", "cloudflared.service"); err != nil {
|
||||
Log.WithError(err).Infof("systemctl disable cloudflared.service error")
|
||||
logger.WithError(err).Infof("systemctl disable cloudflared.service error")
|
||||
return err
|
||||
}
|
||||
if err := runCommand("systemctl", "stop", "cloudflared-update.timer"); err != nil {
|
||||
Log.WithError(err).Infof("systemctl stop cloudflared-update.timer error")
|
||||
logger.WithError(err).Infof("systemctl stop cloudflared-update.timer error")
|
||||
return err
|
||||
}
|
||||
for _, serviceTemplate := range systemdTemplates {
|
||||
if err := serviceTemplate.Remove(); err != nil {
|
||||
Log.WithError(err).Infof("error removing service template")
|
||||
logger.WithError(err).Infof("error removing service template")
|
||||
return err
|
||||
}
|
||||
}
|
||||
Log.Infof("Successfully uninstall cloudflared service")
|
||||
logger.Infof("Successfully uninstall cloudflared service")
|
||||
return nil
|
||||
}
|
||||
|
||||
func uninstallSysv() error {
|
||||
if err := sysvTemplate.Remove(); err != nil {
|
||||
Log.WithError(err).Infof("error removing service template")
|
||||
logger.WithError(err).Infof("error removing service template")
|
||||
return err
|
||||
}
|
||||
for _, i := range [...]string{"2", "3", "4", "5"} {
|
||||
|
@ -287,6 +287,6 @@ func uninstallSysv() error {
|
|||
continue
|
||||
}
|
||||
}
|
||||
Log.Infof("Successfully uninstall cloudflared service")
|
||||
logger.Infof("Successfully uninstall cloudflared service")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ func download(certURL, filePath string) bool {
|
|||
return true
|
||||
}
|
||||
if err != nil {
|
||||
Log.WithError(err).Error("Error fetching certificate")
|
||||
logger.WithError(err).Error("Error fetching certificate")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -179,16 +179,16 @@ func putSuccess(client *http.Client, certURL string) {
|
|||
// indicate success to the relay server
|
||||
req, err := http.NewRequest("PUT", certURL+"/ok", nil)
|
||||
if err != nil {
|
||||
Log.WithError(err).Error("HTTP request error")
|
||||
logger.WithError(err).Error("HTTP request error")
|
||||
return
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
Log.WithError(err).Error("HTTP error")
|
||||
logger.WithError(err).Error("HTTP error")
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
Log.Errorf("Unexpected HTTP error code %d", resp.StatusCode)
|
||||
logger.Errorf("Unexpected HTTP error code %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
const launchAgentIdentifier = "com.cloudflare.cloudflared"
|
||||
const (
|
||||
launchdIdentifier = "com.cloudflare.cloudflared"
|
||||
)
|
||||
|
||||
func runApp(app *cli.App) {
|
||||
app.Commands = append(app.Commands, &cli.Command{
|
||||
|
@ -32,7 +34,7 @@ func runApp(app *cli.App) {
|
|||
}
|
||||
|
||||
var launchdTemplate = ServiceTemplate{
|
||||
Path: installPath(launchAgentIdentifier),
|
||||
Path: installPath(),
|
||||
Content: fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
|
@ -46,9 +48,9 @@ var launchdTemplate = ServiceTemplate{
|
|||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/tmp/%s.out.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/tmp/%s.err.log</string>
|
||||
<string>%s</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>%s</string>
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>SuccessfulExit</key>
|
||||
|
@ -57,54 +59,84 @@ var launchdTemplate = ServiceTemplate{
|
|||
<key>ThrottleInterval</key>
|
||||
<integer>20</integer>
|
||||
</dict>
|
||||
</plist>`, launchAgentIdentifier, launchAgentIdentifier, launchAgentIdentifier),
|
||||
</plist>`, launchdIdentifier, stdoutPath(), stderrPath()),
|
||||
}
|
||||
|
||||
func installPath(launchAgentIdentifier string) string {
|
||||
pathPattern := "~/Library/LaunchAgents/%s.plist"
|
||||
func isRootUser() bool {
|
||||
return os.Geteuid() == 0
|
||||
}
|
||||
|
||||
func installPath() string {
|
||||
// User is root, use /Library/LaunchDaemons instead of home directory
|
||||
if os.Geteuid() == 0 {
|
||||
pathPattern = "/Library/LaunchDaemons/%s.plist"
|
||||
if isRootUser() {
|
||||
return fmt.Sprintf("/Library/LaunchDaemons/%s.plist", launchdIdentifier)
|
||||
}
|
||||
return fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", userHomeDir(), launchdIdentifier)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(pathPattern, launchAgentIdentifier)
|
||||
func stdoutPath() string {
|
||||
if isRootUser() {
|
||||
return fmt.Sprintf("/Library/Logs/%s.out.log", launchdIdentifier)
|
||||
}
|
||||
return fmt.Sprintf("%s/Library/Logs/%s.out.log", userHomeDir(), launchdIdentifier)
|
||||
}
|
||||
|
||||
func stderrPath() string {
|
||||
if isRootUser() {
|
||||
return fmt.Sprintf("/Library/Logs/%s.err.log", launchdIdentifier)
|
||||
}
|
||||
return fmt.Sprintf("%s/Library/Logs/%s.err.log", userHomeDir(), launchdIdentifier)
|
||||
}
|
||||
|
||||
func installLaunchd(c *cli.Context) error {
|
||||
Log.Infof("Installing Argo Tunnel as an user launch agent")
|
||||
if isRootUser() {
|
||||
logger.Infof("Installing Argo Tunnel client as a system launch daemon. " +
|
||||
"Argo Tunnel client will run at boot")
|
||||
} else {
|
||||
logger.Infof("Installing Argo Tunnel client as an user launch agent. " +
|
||||
"Note that Argo Tunnel client will only run when the user is logged in. " +
|
||||
"If you want to run Argo Tunnel client at boot, install with root permission. " +
|
||||
"For more information, visit https://developers.cloudflare.com/argo-tunnel/reference/service/")
|
||||
}
|
||||
etPath, err := os.Executable()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error determining executable path")
|
||||
logger.WithError(err).Infof("error determining executable path")
|
||||
return fmt.Errorf("error determining executable path: %v", err)
|
||||
}
|
||||
templateArgs := ServiceTemplateArgs{Path: etPath}
|
||||
err = launchdTemplate.Generate(&templateArgs)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error generating launchd template")
|
||||
logger.WithError(err).Infof("error generating launchd template")
|
||||
return err
|
||||
}
|
||||
plistPath, err := launchdTemplate.ResolvePath()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error resolving launchd template path")
|
||||
logger.WithError(err).Infof("error resolving launchd template path")
|
||||
return err
|
||||
}
|
||||
Log.Infof("Outputs are logged in %s and %s", fmt.Sprintf("/tmp/%s.out.log", launchAgentIdentifier), fmt.Sprintf("/tmp/%s.err.log", launchAgentIdentifier))
|
||||
|
||||
logger.Infof("Outputs are logged to %s and %s", stderrPath(), stdoutPath())
|
||||
return runCommand("launchctl", "load", plistPath)
|
||||
}
|
||||
|
||||
func uninstallLaunchd(c *cli.Context) error {
|
||||
Log.Infof("Uninstalling Argo Tunnel as an user launch agent")
|
||||
|
||||
if isRootUser() {
|
||||
logger.Infof("Uninstalling Argo Tunnel as a system launch daemon")
|
||||
} else {
|
||||
logger.Infof("Uninstalling Argo Tunnel as an user launch agent")
|
||||
}
|
||||
plistPath, err := launchdTemplate.ResolvePath()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error resolving launchd template path")
|
||||
logger.WithError(err).Infof("error resolving launchd template path")
|
||||
return err
|
||||
}
|
||||
err = runCommand("launchctl", "unload", plistPath)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error unloading")
|
||||
logger.WithError(err).Infof("error unloading")
|
||||
return err
|
||||
}
|
||||
Log.Infof("Outputs are logged in %s and %s", fmt.Sprintf("/tmp/%s.out.log", launchAgentIdentifier), fmt.Sprintf("/tmp/%s.err.log", launchAgentIdentifier))
|
||||
|
||||
logger.Infof("Outputs are logged to %s and %s", stderrPath(), stdoutPath())
|
||||
return launchdTemplate.Remove()
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflared/log"
|
||||
"github.com/cloudflare/cloudflared/metrics"
|
||||
"github.com/cloudflare/cloudflared/origin"
|
||||
"github.com/cloudflare/cloudflared/tlsconfig"
|
||||
|
@ -48,7 +48,7 @@ const (
|
|||
var listeners = gracenet.Net{}
|
||||
var Version = "DEV"
|
||||
var BuildTime = "unknown"
|
||||
var Log *logrus.Logger
|
||||
var logger = log.CreateLogger()
|
||||
var defaultConfigFiles = []string{"config.yml", "config.yaml"}
|
||||
|
||||
// Launchd doesn't set root env variables, so there is default
|
||||
|
@ -59,15 +59,6 @@ var defaultConfigDirs = []string{"~/.cloudflared", "~/.cloudflare-warp", "~/clou
|
|||
// May be closed by the Windows service runner.
|
||||
var shutdownC chan struct{}
|
||||
|
||||
type BuildAndRuntimeInfo struct {
|
||||
GoOS string `json:"go_os"`
|
||||
GoVersion string `json:"go_version"`
|
||||
GoArch string `json:"go_arch"`
|
||||
WarpVersion string `json:"warp_version"`
|
||||
WarpFlags map[string]interface{} `json:"warp_flags"`
|
||||
WarpEnvs map[string]string `json:"warp_envs"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
metrics.RegisterBuildInfo(BuildTime, Version)
|
||||
raven.SetDSN(sentryDSN)
|
||||
|
@ -306,18 +297,17 @@ func main() {
|
|||
return nil
|
||||
}
|
||||
app.Before = func(context *cli.Context) error {
|
||||
Log = logrus.New()
|
||||
inputSource, err := findInputSourceContext(context)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("Cannot load configuration from %s", context.String("config"))
|
||||
logger.WithError(err).Infof("Cannot load configuration from %s", context.String("config"))
|
||||
return err
|
||||
} else if inputSource != nil {
|
||||
err := altsrc.ApplyInputSourceValues(context, inputSource, app.Flags)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("Cannot apply configuration from %s", context.String("config"))
|
||||
logger.WithError(err).Infof("Cannot apply configuration from %s", context.String("config"))
|
||||
return err
|
||||
}
|
||||
Log.Infof("Applied configuration from %s", context.String("config"))
|
||||
logger.Infof("Applied configuration from %s", context.String("config"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -404,45 +394,50 @@ func startServer(c *cli.Context) {
|
|||
// c.NumFlags() == 0 && c.NArg() == 0. For cloudflared to work, the user needs to at
|
||||
// least provide a hostname.
|
||||
if c.NumFlags() == 0 && c.NArg() == 0 && os.Getenv("TUNNEL_HOSTNAME") == "" {
|
||||
Log.Infof("No arguments were provided. You need to at least specify the hostname for this tunnel. See %s", quickStartUrl)
|
||||
logger.Infof("No arguments were provided. You need to at least specify the hostname for this tunnel. See %s", quickStartUrl)
|
||||
cli.ShowAppHelp(c)
|
||||
return
|
||||
}
|
||||
logLevel, err := logrus.ParseLevel(c.String("loglevel"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Unknown logging level specified")
|
||||
logger.WithError(err).Fatal("Unknown logging level specified")
|
||||
}
|
||||
Log.SetLevel(logLevel)
|
||||
logger.SetLevel(logLevel)
|
||||
|
||||
protoLogLevel, err := logrus.ParseLevel(c.String("proto-loglevel"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Unknown protocol logging level specified")
|
||||
logger.WithError(err).Fatal("Unknown protocol logging level specified")
|
||||
}
|
||||
protoLogger := logrus.New()
|
||||
protoLogger.Level = protoLogLevel
|
||||
|
||||
if c.String("logfile") != "" {
|
||||
if err := initLogFile(c, protoLogger); err != nil {
|
||||
Log.Error(err)
|
||||
logger.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
buildInfo := origin.GetBuildInfo()
|
||||
logger.Infof("Build info: %+v", *buildInfo)
|
||||
logger.Infof("Version %s", Version)
|
||||
logClientOptions(c)
|
||||
|
||||
if c.IsSet("proxy-dns") {
|
||||
port := c.Int("proxy-dns-port")
|
||||
if port <= 0 || port > 65535 {
|
||||
Log.Fatal("The 'proxy-dns-port' must be a valid port number in <1, 65535> range.")
|
||||
logger.Fatal("The 'proxy-dns-port' must be a valid port number in <1, 65535> range.")
|
||||
}
|
||||
wg.Add(1)
|
||||
listener, err := tunneldns.CreateListener(c.String("proxy-dns-address"), uint16(port), c.StringSlice("proxy-dns-upstream"))
|
||||
if err != nil {
|
||||
close(dnsReadySignal)
|
||||
listener.Stop()
|
||||
Log.WithError(err).Fatal("Cannot create the DNS over HTTPS proxy server")
|
||||
logger.WithError(err).Fatal("Cannot create the DNS over HTTPS proxy server")
|
||||
}
|
||||
go func() {
|
||||
err := listener.Start(dnsReadySignal)
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Cannot start the DNS over HTTPS proxy server")
|
||||
logger.WithError(err).Fatal("Cannot start the DNS over HTTPS proxy server")
|
||||
} else {
|
||||
<-shutdownC
|
||||
}
|
||||
|
@ -453,13 +448,14 @@ func startServer(c *cli.Context) {
|
|||
close(dnsReadySignal)
|
||||
}
|
||||
|
||||
if isAutoupdateEnabled(c) {
|
||||
isRunningFromTerminal := isRunningFromTerminal()
|
||||
if isAutoupdateEnabled(c, isRunningFromTerminal) {
|
||||
// Wait for proxy-dns to come up (if used)
|
||||
<-dnsReadySignal
|
||||
if initUpdate() {
|
||||
return
|
||||
}
|
||||
Log.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq"))
|
||||
logger.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq"))
|
||||
go autoupdate(c.Duration("autoupdate-freq"), shutdownC)
|
||||
}
|
||||
|
||||
|
@ -473,7 +469,7 @@ func startServer(c *cli.Context) {
|
|||
|
||||
hostname, err := validation.ValidateHostname(c.String("hostname"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Invalid hostname")
|
||||
logger.WithError(err).Fatal("Invalid hostname")
|
||||
}
|
||||
clientID := c.String("id")
|
||||
if !c.IsSet("id") {
|
||||
|
@ -482,7 +478,7 @@ func startServer(c *cli.Context) {
|
|||
|
||||
tags, err := NewTagSliceFromCLI(c.StringSlice("tag"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Tag parse failure")
|
||||
logger.WithError(err).Fatal("Tag parse failure")
|
||||
}
|
||||
|
||||
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID})
|
||||
|
@ -491,7 +487,7 @@ func startServer(c *cli.Context) {
|
|||
listener, err := createListener("127.0.0.1:")
|
||||
if err != nil {
|
||||
listener.Close()
|
||||
Log.WithError(err).Fatal("Cannot start Hello World Server")
|
||||
logger.WithError(err).Fatal("Cannot start Hello World Server")
|
||||
}
|
||||
go func() {
|
||||
startHelloWorldServer(listener, shutdownC)
|
||||
|
@ -503,26 +499,26 @@ func startServer(c *cli.Context) {
|
|||
|
||||
url, err := validateUrl(c)
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Error validating url")
|
||||
logger.WithError(err).Fatal("Error validating url")
|
||||
}
|
||||
Log.Infof("Proxying tunnel requests to %s", url)
|
||||
logger.Infof("Proxying tunnel requests to %s", url)
|
||||
|
||||
// Fail if the user provided an old authentication method
|
||||
if c.IsSet("api-key") || c.IsSet("api-email") || c.IsSet("api-ca-key") {
|
||||
Log.Fatal("You don't need to give us your api-key anymore. Please use the new log in method. Just run cloudflared login")
|
||||
logger.Fatal("You don't need to give us your api-key anymore. Please use the new log in method. Just run cloudflared login")
|
||||
}
|
||||
|
||||
// Check that the user has acquired a certificate using the log in command
|
||||
originCertPath, err := homedir.Expand(c.String("origincert"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatalf("Cannot resolve path %s", c.String("origincert"))
|
||||
logger.WithError(err).Fatalf("Cannot resolve path %s", c.String("origincert"))
|
||||
}
|
||||
ok, err := fileExists(originCertPath)
|
||||
if err != nil {
|
||||
Log.Fatalf("Cannot check if origin cert exists at path %s", c.String("origincert"))
|
||||
logger.Fatalf("Cannot check if origin cert exists at path %s", c.String("origincert"))
|
||||
}
|
||||
if !ok {
|
||||
Log.Fatalf(`Cannot find a valid certificate for your origin at the path:
|
||||
logger.Fatalf(`Cannot find a valid certificate for your origin at the path:
|
||||
|
||||
%s
|
||||
|
||||
|
@ -535,7 +531,7 @@ If you don't have a certificate signed by Cloudflare, run the command:
|
|||
// Easier to send the certificate as []byte via RPC than decoding it at this point
|
||||
originCert, err := ioutil.ReadFile(originCertPath)
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatalf("Cannot read %s to load origin certificate", originCertPath)
|
||||
logger.WithError(err).Fatalf("Cannot read %s to load origin certificate", originCertPath)
|
||||
}
|
||||
|
||||
tunnelMetrics := origin.NewTunnelMetrics()
|
||||
|
@ -558,27 +554,29 @@ If you don't have a certificate signed by Cloudflare, run the command:
|
|||
}
|
||||
|
||||
tunnelConfig := &origin.TunnelConfig{
|
||||
EdgeAddrs: c.StringSlice("edge"),
|
||||
OriginUrl: url,
|
||||
Hostname: hostname,
|
||||
OriginCert: originCert,
|
||||
TlsConfig: tlsconfig.CreateTunnelConfig(c, c.StringSlice("edge")),
|
||||
ClientTlsConfig: httpTransport.TLSClientConfig,
|
||||
Retries: c.Uint("retries"),
|
||||
HeartbeatInterval: c.Duration("heartbeat-interval"),
|
||||
MaxHeartbeats: c.Uint64("heartbeat-count"),
|
||||
ClientID: clientID,
|
||||
ReportedVersion: Version,
|
||||
LBPool: c.String("lb-pool"),
|
||||
Tags: tags,
|
||||
HAConnections: c.Int("ha-connections"),
|
||||
HTTPTransport: httpTransport,
|
||||
Metrics: tunnelMetrics,
|
||||
MetricsUpdateFreq: c.Duration("metrics-update-freq"),
|
||||
ProtocolLogger: protoLogger,
|
||||
Logger: Log,
|
||||
IsAutoupdated: c.Bool("is-autoupdated"),
|
||||
GracePeriod: c.Duration("grace-period"),
|
||||
EdgeAddrs: c.StringSlice("edge"),
|
||||
OriginUrl: url,
|
||||
Hostname: hostname,
|
||||
OriginCert: originCert,
|
||||
TlsConfig: tlsconfig.CreateTunnelConfig(c, c.StringSlice("edge")),
|
||||
ClientTlsConfig: httpTransport.TLSClientConfig,
|
||||
Retries: c.Uint("retries"),
|
||||
HeartbeatInterval: c.Duration("heartbeat-interval"),
|
||||
MaxHeartbeats: c.Uint64("heartbeat-count"),
|
||||
ClientID: clientID,
|
||||
BuildInfo: buildInfo,
|
||||
ReportedVersion: Version,
|
||||
LBPool: c.String("lb-pool"),
|
||||
Tags: tags,
|
||||
HAConnections: c.Int("ha-connections"),
|
||||
HTTPTransport: httpTransport,
|
||||
Metrics: tunnelMetrics,
|
||||
MetricsUpdateFreq: c.Duration("metrics-update-freq"),
|
||||
ProtocolLogger: protoLogger,
|
||||
Logger: logger,
|
||||
IsAutoupdated: c.Bool("is-autoupdated"),
|
||||
GracePeriod: c.Duration("grace-period"),
|
||||
RunFromTerminal: isRunningFromTerminal,
|
||||
}
|
||||
|
||||
go writePidFile(connectedSignal, c.String("pidfile"))
|
||||
|
@ -595,21 +593,21 @@ func runServer(c *cli.Context, wg *sync.WaitGroup, errC chan error, shutdownC ch
|
|||
wg.Add(1)
|
||||
metricsListener, err := listeners.Listen("tcp", c.String("metrics"))
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Error opening metrics server listener")
|
||||
logger.WithError(err).Fatal("Error opening metrics server listener")
|
||||
}
|
||||
go func() {
|
||||
errC <- metrics.ServeMetrics(metricsListener, shutdownC)
|
||||
errC <- metrics.ServeMetrics(metricsListener, shutdownC, logger)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
var errCode int
|
||||
err = WaitForSignal(errC, shutdownC)
|
||||
if err != nil {
|
||||
Log.WithError(err).Fatal("Quitting due to error")
|
||||
logger.WithError(err).Fatal("Quitting due to error")
|
||||
raven.CaptureErrorAndWait(err, nil)
|
||||
errCode = 1
|
||||
} else {
|
||||
Log.Info("Graceful shutdown...")
|
||||
logger.Info("Graceful shutdown...")
|
||||
}
|
||||
// Wait for clean exit, discarding all errors
|
||||
go func() {
|
||||
|
@ -648,7 +646,7 @@ func initUpdate() bool {
|
|||
if updateApplied() {
|
||||
os.Args = append(os.Args, "--is-autoupdated=true")
|
||||
if _, err := listeners.StartProcess(); err != nil {
|
||||
Log.WithError(err).Error("Unable to restart server automatically")
|
||||
logger.WithError(err).Error("Unable to restart server automatically")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -661,7 +659,7 @@ func autoupdate(freq time.Duration, shutdownC chan struct{}) {
|
|||
if updateApplied() {
|
||||
os.Args = append(os.Args, "--is-autoupdated=true")
|
||||
if _, err := listeners.StartProcess(); err != nil {
|
||||
Log.WithError(err).Error("Unable to restart server automatically")
|
||||
logger.WithError(err).Error("Unable to restart server automatically")
|
||||
}
|
||||
close(shutdownC)
|
||||
return
|
||||
|
@ -673,11 +671,11 @@ func autoupdate(freq time.Duration, shutdownC chan struct{}) {
|
|||
func updateApplied() bool {
|
||||
releaseInfo := checkForUpdates()
|
||||
if releaseInfo.Updated {
|
||||
Log.Infof("Updated to version %s", releaseInfo.Version)
|
||||
logger.Infof("Updated to version %s", releaseInfo.Version)
|
||||
return true
|
||||
}
|
||||
if releaseInfo.Error != nil {
|
||||
Log.WithError(releaseInfo.Error).Error("Update check failed")
|
||||
logger.WithError(releaseInfo.Error).Error("Update check failed")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -748,7 +746,7 @@ func writePidFile(waitForSignal chan struct{}, pidFile string) {
|
|||
}
|
||||
file, err := os.Create(pidFile)
|
||||
if err != nil {
|
||||
Log.WithError(err).Errorf("Unable to write pid to %s", pidFile)
|
||||
logger.WithError(err).Errorf("Unable to write pid to %s", pidFile)
|
||||
}
|
||||
defer file.Close()
|
||||
fmt.Fprintf(file, "%d", os.Getpid())
|
||||
|
@ -790,16 +788,22 @@ func initLogFile(c *cli.Context, protoLogger *logrus.Logger) error {
|
|||
logrus.PanicLevel: filePath,
|
||||
}
|
||||
|
||||
Log.Hooks.Add(lfshook.NewHook(pathMap, &logrus.JSONFormatter{}))
|
||||
logger.Hooks.Add(lfshook.NewHook(pathMap, &logrus.JSONFormatter{}))
|
||||
protoLogger.Hooks.Add(lfshook.NewHook(pathMap, &logrus.JSONFormatter{}))
|
||||
|
||||
flags := make(map[string]interface{})
|
||||
envs := make(map[string]string)
|
||||
return nil
|
||||
}
|
||||
|
||||
func logClientOptions(c *cli.Context) {
|
||||
flags := make(map[string]interface{})
|
||||
for _, flag := range c.LocalFlagNames() {
|
||||
flags[flag] = c.Generic(flag)
|
||||
}
|
||||
if len(flags) > 0 {
|
||||
logger.Infof("Flags %v", flags)
|
||||
}
|
||||
|
||||
envs := make(map[string]string)
|
||||
// Find env variables for Argo Tunnel
|
||||
for _, env := range os.Environ() {
|
||||
// All Argo Tunnel env variables start with TUNNEL_
|
||||
|
@ -810,24 +814,33 @@ func initLogFile(c *cli.Context, protoLogger *logrus.Logger) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.Infof("Argo Tunnel build and runtime configuration: %+v", BuildAndRuntimeInfo{
|
||||
GoOS: runtime.GOOS,
|
||||
GoVersion: runtime.Version(),
|
||||
GoArch: runtime.GOARCH,
|
||||
WarpVersion: Version,
|
||||
WarpFlags: flags,
|
||||
WarpEnvs: envs,
|
||||
})
|
||||
|
||||
return nil
|
||||
if len(envs) > 0 {
|
||||
logger.Infof("Environmental variables %v", envs)
|
||||
}
|
||||
}
|
||||
|
||||
func isAutoupdateEnabled(c *cli.Context) bool {
|
||||
if terminal.IsTerminal(int(os.Stdout.Fd())) {
|
||||
Log.Info(noAutoupdateMessage)
|
||||
func isAutoupdateEnabled(c *cli.Context, isRunningFromTerminal bool) bool {
|
||||
if isRunningFromTerminal {
|
||||
logger.Info(noAutoupdateMessage)
|
||||
return false
|
||||
}
|
||||
|
||||
return !c.Bool("no-autoupdate") && c.Duration("autoupdate-freq") != 0
|
||||
}
|
||||
|
||||
|
||||
func isRunningFromTerminal() bool {
|
||||
return terminal.IsTerminal(int(os.Stdout.Fd()))
|
||||
}
|
||||
|
||||
func userHomeDir() string {
|
||||
// This returns the home dir of the executing user using OS-specific method
|
||||
// for discovering the home dir. It's not recommended to call this function
|
||||
// when the user has root permission as $HOME depends on what options the user
|
||||
// use with sudo.
|
||||
homeDir, err := homedir.Dir()
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("Cannot determine home directory for the user.")
|
||||
}
|
||||
return homeDir
|
||||
}
|
||||
|
|
|
@ -73,21 +73,21 @@ func runCommand(command string, args ...string) error {
|
|||
cmd := exec.Command(command, args...)
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error getting stderr pipe")
|
||||
logger.WithError(err).Infof("error getting stderr pipe")
|
||||
return fmt.Errorf("error getting stderr pipe: %v", err)
|
||||
}
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("error starting %s", command)
|
||||
logger.WithError(err).Infof("error starting %s", command)
|
||||
return fmt.Errorf("error starting %s: %v", command, err)
|
||||
}
|
||||
commandErr, _ := ioutil.ReadAll(stderr)
|
||||
if len(commandErr) > 0 {
|
||||
Log.Errorf("%s: %s", command, commandErr)
|
||||
logger.Errorf("%s: %s", command, commandErr)
|
||||
}
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("%s returned error", command)
|
||||
logger.WithError(err).Infof("%s returned error", command)
|
||||
return fmt.Errorf("%s returned with error: %v", command, err)
|
||||
}
|
||||
return nil
|
||||
|
@ -159,7 +159,7 @@ func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile strin
|
|||
destConfigPath := filepath.Join(serviceConfigDir, defaultConfigFile)
|
||||
destFile, exists, err := openFile(destConfigPath, true)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("cannot open %s", destConfigPath)
|
||||
logger.WithError(err).Infof("cannot open %s", destConfigPath)
|
||||
return err
|
||||
} else if exists {
|
||||
// config already exists, do nothing
|
||||
|
@ -185,7 +185,7 @@ func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile strin
|
|||
if err != nil {
|
||||
return fmt.Errorf("unable to copy %s to %s: %v", srcConfigPath, destConfigPath, err)
|
||||
}
|
||||
Log.Infof("Copied %s to %s", srcConfigPath, destConfigPath)
|
||||
logger.Infof("Copied %s to %s", srcConfigPath, destConfigPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -41,7 +41,7 @@ func runApp(app *cli.App) {
|
|||
|
||||
isIntSess, err := svc.IsAnInteractiveSession()
|
||||
if err != nil {
|
||||
Log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
|
||||
logger.Fatalf("failed to determine if we are running in an interactive session: %v", err)
|
||||
}
|
||||
|
||||
if isIntSess {
|
||||
|
@ -51,7 +51,7 @@ func runApp(app *cli.App) {
|
|||
|
||||
elog, err := eventlog.Open(windowsServiceName)
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("Cannot open event log for %s", windowsServiceName)
|
||||
logger.WithError(err).Infof("Cannot open event log for %s", windowsServiceName)
|
||||
return
|
||||
}
|
||||
defer elog.Close()
|
||||
|
@ -104,62 +104,62 @@ loop:
|
|||
}
|
||||
|
||||
func installWindowsService(c *cli.Context) error {
|
||||
Log.Infof("Installing Argo Tunnel Windows service")
|
||||
logger.Infof("Installing Argo Tunnel Windows service")
|
||||
exepath, err := os.Executable()
|
||||
if err != nil {
|
||||
Log.Infof("Cannot find path name that start the process")
|
||||
logger.Infof("Cannot find path name that start the process")
|
||||
return err
|
||||
}
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
Log.WithError(err).Infof("Cannot establish a connection to the service control manager")
|
||||
logger.WithError(err).Infof("Cannot establish a connection to the service control manager")
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(windowsServiceName)
|
||||
if err == nil {
|
||||
s.Close()
|
||||
Log.Errorf("service %s already exists", windowsServiceName)
|
||||
logger.Errorf("service %s already exists", windowsServiceName)
|
||||
return fmt.Errorf("service %s already exists", windowsServiceName)
|
||||
}
|
||||
config := mgr.Config{StartType: mgr.StartAutomatic, DisplayName: windowsServiceDescription}
|
||||
s, err = m.CreateService(windowsServiceName, exepath, config)
|
||||
if err != nil {
|
||||
Log.Infof("Cannot install service %s", windowsServiceName)
|
||||
logger.Infof("Cannot install service %s", windowsServiceName)
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
err = eventlog.InstallAsEventCreate(windowsServiceName, eventlog.Error|eventlog.Warning|eventlog.Info)
|
||||
if err != nil {
|
||||
s.Delete()
|
||||
Log.WithError(err).Infof("Cannot install event logger")
|
||||
logger.WithError(err).Infof("Cannot install event logger")
|
||||
return fmt.Errorf("SetupEventLogSource() failed: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func uninstallWindowsService(c *cli.Context) error {
|
||||
Log.Infof("Uninstalling Argo Tunnel Windows Service")
|
||||
logger.Infof("Uninstalling Argo Tunnel Windows Service")
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
Log.Infof("Cannot establish a connection to the service control manager")
|
||||
logger.Infof("Cannot establish a connection to the service control manager")
|
||||
return err
|
||||
}
|
||||
defer m.Disconnect()
|
||||
s, err := m.OpenService(windowsServiceName)
|
||||
if err != nil {
|
||||
Log.Infof("service %s is not installed", windowsServiceName)
|
||||
logger.Infof("service %s is not installed", windowsServiceName)
|
||||
return fmt.Errorf("service %s is not installed", windowsServiceName)
|
||||
}
|
||||
defer s.Close()
|
||||
err = s.Delete()
|
||||
if err != nil {
|
||||
Log.Errorf("Cannot delete service %s", windowsServiceName)
|
||||
logger.Errorf("Cannot delete service %s", windowsServiceName)
|
||||
return err
|
||||
}
|
||||
err = eventlog.Remove(windowsServiceName)
|
||||
if err != nil {
|
||||
Log.Infof("Cannot remove event logger")
|
||||
logger.Infof("Cannot remove event logger")
|
||||
return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// this forks the logrus json formatter to rename msg -> message as that's the
|
||||
// expected field. Ideally the logger should make it easier for us.
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultTimestampFormat = time.RFC3339
|
||||
)
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func CreateLogger() *logrus.Logger {
|
||||
logger := logrus.New()
|
||||
logger.Out = colorable.NewColorableStderr()
|
||||
logger.Formatter = &logrus.TextFormatter{ForceColors: true}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
data := make(logrus.Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
data["time"] = entry.Time.Format(timestampFormat)
|
||||
data["message"] = entry.Message
|
||||
data["level"] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
//
|
||||
// Would just silently drop the user provided level. Instead with this code
|
||||
// it'll logged as:
|
||||
//
|
||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||
//
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data logrus.Fields) {
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
}
|
||||
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
}
|
||||
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -21,7 +21,7 @@ const (
|
|||
startupTime = time.Millisecond * 500
|
||||
)
|
||||
|
||||
func ServeMetrics(l net.Listener, shutdownC <-chan struct{}) (err error) {
|
||||
func ServeMetrics(l net.Listener, shutdownC <-chan struct{}, logger *logrus.Logger) (err error) {
|
||||
var wg sync.WaitGroup
|
||||
// Metrics port is privileged, so no need for further access control
|
||||
trace.AuthRequest = func(*http.Request) (bool, bool) { return true, true }
|
||||
|
@ -39,7 +39,7 @@ func ServeMetrics(l net.Listener, shutdownC <-chan struct{}) (err error) {
|
|||
defer wg.Done()
|
||||
err = server.Serve(l)
|
||||
}()
|
||||
log.WithField("addr", l.Addr()).Info("Starting metrics server")
|
||||
logger.WithField("addr", l.Addr()).Info("Starting metrics server")
|
||||
// server.Serve will hang if server.Shutdown is called before the server is
|
||||
// fully started up. So add artificial delay.
|
||||
time.Sleep(startupTime)
|
||||
|
@ -51,10 +51,10 @@ func ServeMetrics(l net.Listener, shutdownC <-chan struct{}) (err error) {
|
|||
|
||||
wg.Wait()
|
||||
if err == http.ErrServerClosed {
|
||||
log.Info("Metrics server stopped")
|
||||
logger.Info("Metrics server stopped")
|
||||
return nil
|
||||
}
|
||||
log.WithError(err).Error("Metrics server quit with error")
|
||||
logger.WithError(err).Error("Metrics server quit with error")
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package origin
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type BuildInfo struct {
|
||||
GoOS string `json:"go_os"`
|
||||
GoVersion string `json:"go_version"`
|
||||
GoArch string `json:"go_arch"`
|
||||
}
|
||||
|
||||
func GetBuildInfo() *BuildInfo {
|
||||
return &BuildInfo{
|
||||
GoOS: runtime.GOOS,
|
||||
GoVersion: runtime.Version(),
|
||||
GoArch: runtime.GOARCH,
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ type muxerMetrics struct {
|
|||
outBoundRateMax *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
type tunnelMetrics struct {
|
||||
type TunnelMetrics struct {
|
||||
haConnections prometheus.Gauge
|
||||
totalRequests prometheus.Counter
|
||||
requestsPerTunnel *prometheus.CounterVec
|
||||
|
@ -229,7 +229,7 @@ func convertRTTMilliSec(t time.Duration) float64 {
|
|||
}
|
||||
|
||||
// Metrics that can be collected without asking the edge
|
||||
func NewTunnelMetrics() *tunnelMetrics {
|
||||
func NewTunnelMetrics() *TunnelMetrics {
|
||||
haConnections := prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "ha_connections",
|
||||
|
@ -305,7 +305,7 @@ func NewTunnelMetrics() *tunnelMetrics {
|
|||
)
|
||||
prometheus.MustRegister(serverLocations)
|
||||
|
||||
return &tunnelMetrics{
|
||||
return &TunnelMetrics{
|
||||
haConnections: haConnections,
|
||||
totalRequests: totalRequests,
|
||||
requestsPerTunnel: requestsPerTunnel,
|
||||
|
@ -322,19 +322,19 @@ func NewTunnelMetrics() *tunnelMetrics {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) incrementHaConnections() {
|
||||
func (t *TunnelMetrics) incrementHaConnections() {
|
||||
t.haConnections.Inc()
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) decrementHaConnections() {
|
||||
func (t *TunnelMetrics) decrementHaConnections() {
|
||||
t.haConnections.Dec()
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) updateMuxerMetrics(connectionID string, metrics *h2mux.MuxerMetrics) {
|
||||
func (t *TunnelMetrics) updateMuxerMetrics(connectionID string, metrics *h2mux.MuxerMetrics) {
|
||||
t.muxerMetrics.update(connectionID, metrics)
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) incrementRequests(connectionID string) {
|
||||
func (t *TunnelMetrics) incrementRequests(connectionID string) {
|
||||
t.concurrentRequestsLock.Lock()
|
||||
var concurrentRequests uint64
|
||||
var ok bool
|
||||
|
@ -356,25 +356,25 @@ func (t *tunnelMetrics) incrementRequests(connectionID string) {
|
|||
t.concurrentRequestsPerTunnel.WithLabelValues(connectionID).Inc()
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) decrementConcurrentRequests(connectionID string) {
|
||||
func (t *TunnelMetrics) decrementConcurrentRequests(connectionID string) {
|
||||
t.concurrentRequestsLock.Lock()
|
||||
if _, ok := t.concurrentRequests[connectionID]; ok {
|
||||
t.concurrentRequests[connectionID] -= 1
|
||||
} else {
|
||||
Log.Error("Concurrent requests per tunnel metrics went wrong; you can't decrement concurrent requests count without increment it first.")
|
||||
logger.Error("Concurrent requests per tunnel metrics went wrong; you can't decrement concurrent requests count without increment it first.")
|
||||
}
|
||||
t.concurrentRequestsLock.Unlock()
|
||||
|
||||
t.concurrentRequestsPerTunnel.WithLabelValues(connectionID).Dec()
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) incrementResponses(connectionID, code string) {
|
||||
func (t *TunnelMetrics) incrementResponses(connectionID, code string) {
|
||||
t.responseByCode.WithLabelValues(code).Inc()
|
||||
t.responseCodePerTunnel.WithLabelValues(connectionID, code).Inc()
|
||||
|
||||
}
|
||||
|
||||
func (t *tunnelMetrics) registerServerLocation(connectionID, loc string) {
|
||||
func (t *TunnelMetrics) registerServerLocation(connectionID, loc string) {
|
||||
t.locationLock.Lock()
|
||||
defer t.locationLock.Unlock()
|
||||
if oldLoc, ok := t.oldServerLocations[connectionID]; ok && oldLoc == loc {
|
||||
|
|
|
@ -73,7 +73,7 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) err
|
|||
case tunnelError := <-s.tunnelErrors:
|
||||
tunnelsActive--
|
||||
if tunnelError.err != nil {
|
||||
Log.WithError(tunnelError.err).Warn("Tunnel disconnected due to error")
|
||||
logger.WithError(tunnelError.err).Warn("Tunnel disconnected due to error")
|
||||
tunnelsWaiting = append(tunnelsWaiting, tunnelError.index)
|
||||
s.waitForNextTunnel(tunnelError.index)
|
||||
|
||||
|
@ -109,10 +109,10 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) err
|
|||
s.lastResolve = time.Now()
|
||||
s.resolverC = nil
|
||||
if result.err == nil {
|
||||
Log.Debug("Service discovery refresh complete")
|
||||
logger.Debug("Service discovery refresh complete")
|
||||
s.edgeIPs = result.edgeIPs
|
||||
} else {
|
||||
Log.WithError(result.err).Error("Service discovery error")
|
||||
logger.WithError(result.err).Error("Service discovery error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,12 +121,12 @@ func (s *Supervisor) Run(ctx context.Context, connectedSignal chan struct{}) err
|
|||
func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct{}) error {
|
||||
edgeIPs, err := ResolveEdgeIPs(s.config.EdgeAddrs)
|
||||
if err != nil {
|
||||
Log.Infof("ResolveEdgeIPs err")
|
||||
logger.Infof("ResolveEdgeIPs err")
|
||||
return err
|
||||
}
|
||||
s.edgeIPs = edgeIPs
|
||||
if s.config.HAConnections > len(edgeIPs) {
|
||||
Log.Warnf("You requested %d HA connections but I can give you at most %d.", s.config.HAConnections, len(edgeIPs))
|
||||
logger.Warnf("You requested %d HA connections but I can give you at most %d.", s.config.HAConnections, len(edgeIPs))
|
||||
s.config.HAConnections = len(edgeIPs)
|
||||
}
|
||||
s.lastResolve = time.Now()
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -28,7 +27,7 @@ import (
|
|||
rpc "zombiezen.com/go/capnproto2/rpc"
|
||||
)
|
||||
|
||||
var Log *logrus.Logger
|
||||
var logger *logrus.Logger
|
||||
|
||||
const (
|
||||
dialTimeout = 15 * time.Second
|
||||
|
@ -48,17 +47,19 @@ type TunnelConfig struct {
|
|||
HeartbeatInterval time.Duration
|
||||
MaxHeartbeats uint64
|
||||
ClientID string
|
||||
BuildInfo *BuildInfo
|
||||
ReportedVersion string
|
||||
LBPool string
|
||||
Tags []tunnelpogs.Tag
|
||||
HAConnections int
|
||||
HTTPTransport http.RoundTripper
|
||||
Metrics *tunnelMetrics
|
||||
Metrics *TunnelMetrics
|
||||
MetricsUpdateFreq time.Duration
|
||||
ProtocolLogger *logrus.Logger
|
||||
Logger *logrus.Logger
|
||||
IsAutoupdated bool
|
||||
GracePeriod time.Duration
|
||||
RunFromTerminal bool
|
||||
}
|
||||
|
||||
type dialError struct {
|
||||
|
@ -92,18 +93,19 @@ func (c *TunnelConfig) RegistrationOptions(connectionID uint8, OriginLocalIP str
|
|||
return &tunnelpogs.RegistrationOptions{
|
||||
ClientID: c.ClientID,
|
||||
Version: c.ReportedVersion,
|
||||
OS: fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH),
|
||||
OS: fmt.Sprintf("%s_%s", c.BuildInfo.GoOS, c.BuildInfo.GoArch),
|
||||
ExistingTunnelPolicy: policy,
|
||||
PoolName: c.LBPool,
|
||||
Tags: c.Tags,
|
||||
ConnectionID: connectionID,
|
||||
OriginLocalIP: OriginLocalIP,
|
||||
IsAutoupdated: c.IsAutoupdated,
|
||||
RunFromTerminal: c.RunFromTerminal,
|
||||
}
|
||||
}
|
||||
|
||||
func StartTunnelDaemon(config *TunnelConfig, shutdownC <-chan struct{}, connectedSignal chan struct{}) error {
|
||||
Log = config.Logger
|
||||
logger = config.Logger
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
<-shutdownC
|
||||
|
@ -138,7 +140,7 @@ func ServeTunnelLoop(ctx context.Context, config *TunnelConfig, addr *net.TCPAdd
|
|||
err, recoverable := ServeTunnel(ctx, config, addr, connectionID, connectedFuse, &backoff)
|
||||
if recoverable {
|
||||
if duration, ok := backoff.GetBackoffDuration(ctx); ok {
|
||||
Log.Infof("Retrying in %s seconds", duration)
|
||||
logger.Infof("Retrying in %s seconds", duration)
|
||||
backoff.Backoff(ctx)
|
||||
continue
|
||||
}
|
||||
|
@ -171,7 +173,7 @@ func ServeTunnel(
|
|||
// Returns error from parsing the origin URL or handshake errors
|
||||
handler, originLocalIP, err := NewTunnelHandler(ctx, config, addr.String(), connectionID)
|
||||
if err != nil {
|
||||
errLog := Log.WithError(err)
|
||||
errLog := logger.WithError(err)
|
||||
switch err.(type) {
|
||||
case dialError:
|
||||
errLog.Error("Unable to dial edge")
|
||||
|
@ -218,21 +220,21 @@ func ServeTunnel(
|
|||
registerErr := <-registerErrC
|
||||
wg.Wait()
|
||||
if err != nil {
|
||||
Log.WithError(err).Error("Tunnel error")
|
||||
logger.WithError(err).Error("Tunnel error")
|
||||
return err, true
|
||||
}
|
||||
if registerErr != nil {
|
||||
// Don't retry on errors like entitlement failure or version too old
|
||||
if e, ok := registerErr.(printableRegisterTunnelError); ok {
|
||||
Log.Error(e)
|
||||
logger.Error(e)
|
||||
return e.cause, !e.permanent
|
||||
} else if e, ok := registerErr.(dupConnRegisterTunnelError); ok {
|
||||
Log.Info("Already connected to this server, selecting a different one")
|
||||
logger.Info("Already connected to this server, selecting a different one")
|
||||
return e, true
|
||||
}
|
||||
// Only log errors to Sentry that may have been caused by the client side, to reduce dupes
|
||||
raven.CaptureError(registerErr, nil)
|
||||
Log.Error("Cannot register")
|
||||
logger.Error("Cannot register")
|
||||
return err, true
|
||||
}
|
||||
return nil, false
|
||||
|
@ -249,7 +251,7 @@ func IsRPCStreamResponse(headers []h2mux.Header) bool {
|
|||
}
|
||||
|
||||
func RegisterTunnel(ctx context.Context, muxer *h2mux.Muxer, config *TunnelConfig, connectionID uint8, originLocalIP string) error {
|
||||
logger := Log.WithField("subsystem", "rpc")
|
||||
logger := logger.WithField("subsystem", "rpc")
|
||||
logger.Debug("initiating RPC stream to register")
|
||||
stream, err := muxer.OpenStream([]h2mux.Header{
|
||||
{Name: ":method", Value: "RPC"},
|
||||
|
@ -304,7 +306,7 @@ func RegisterTunnel(ctx context.Context, muxer *h2mux.Muxer, config *TunnelConfi
|
|||
}
|
||||
|
||||
func UnregisterTunnel(muxer *h2mux.Muxer, gracePeriod time.Duration) error {
|
||||
logger := Log.WithField("subsystem", "rpc")
|
||||
logger := logger.WithField("subsystem", "rpc")
|
||||
logger.Debug("initiating RPC stream to unregister")
|
||||
stream, err := muxer.OpenStream([]h2mux.Header{
|
||||
{Name: ":method", Value: "RPC"},
|
||||
|
@ -335,7 +337,7 @@ func UnregisterTunnel(muxer *h2mux.Muxer, gracePeriod time.Duration) error {
|
|||
func LogServerInfo(logger *logrus.Entry,
|
||||
promise tunnelrpc.ServerInfo_Promise,
|
||||
connectionID uint8,
|
||||
metrics *tunnelMetrics,
|
||||
metrics *TunnelMetrics,
|
||||
) {
|
||||
serverInfoMessage, err := promise.Struct()
|
||||
if err != nil {
|
||||
|
@ -347,7 +349,7 @@ func LogServerInfo(logger *logrus.Entry,
|
|||
logger.WithError(err).Warn("Failed to retrieve server information")
|
||||
return
|
||||
}
|
||||
Log.Infof("Connected to %s", serverInfo.LocationName)
|
||||
logger.Infof("Connected to %s", serverInfo.LocationName)
|
||||
metrics.registerServerLocation(uint8ToString(connectionID), serverInfo.LocationName)
|
||||
}
|
||||
|
||||
|
@ -398,7 +400,7 @@ type TunnelHandler struct {
|
|||
httpClient http.RoundTripper
|
||||
tlsConfig *tls.Config
|
||||
tags []tunnelpogs.Tag
|
||||
metrics *tunnelMetrics
|
||||
metrics *TunnelMetrics
|
||||
// connectionID is only used by metrics, and prometheus requires labels to be string
|
||||
connectionID string
|
||||
}
|
||||
|
@ -407,12 +409,12 @@ var dialer = net.Dialer{DualStack: true}
|
|||
|
||||
// NewTunnelHandler returns a TunnelHandler, origin LAN IP and error
|
||||
func NewTunnelHandler(ctx context.Context, config *TunnelConfig, addr string, connectionID uint8) (*TunnelHandler, string, error) {
|
||||
url, err := validation.ValidateUrl(config.OriginUrl)
|
||||
originURL, err := validation.ValidateUrl(config.OriginUrl)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("Unable to parse origin url %#v", url)
|
||||
return nil, "", fmt.Errorf("Unable to parse origin url %#v", originURL)
|
||||
}
|
||||
h := &TunnelHandler{
|
||||
originUrl: url,
|
||||
originUrl: originURL,
|
||||
httpClient: config.HTTPTransport,
|
||||
tlsConfig: config.ClientTlsConfig,
|
||||
tags: config.Tags,
|
||||
|
@ -464,11 +466,11 @@ func (h *TunnelHandler) ServeStream(stream *h2mux.MuxedStream) error {
|
|||
h.metrics.incrementRequests(h.connectionID)
|
||||
req, err := http.NewRequest("GET", h.originUrl, h2mux.MuxedStreamReader{MuxedStream: stream})
|
||||
if err != nil {
|
||||
Log.WithError(err).Panic("Unexpected error from http.NewRequest")
|
||||
logger.WithError(err).Panic("Unexpected error from http.NewRequest")
|
||||
}
|
||||
err = H2RequestHeadersToH1Request(stream.Headers, req)
|
||||
if err != nil {
|
||||
Log.WithError(err).Error("invalid request received")
|
||||
logger.WithError(err).Error("invalid request received")
|
||||
}
|
||||
h.AppendTagHeaders(req)
|
||||
cfRay := FindCfRayHeader(req)
|
||||
|
@ -501,7 +503,7 @@ func (h *TunnelHandler) ServeStream(stream *h2mux.MuxedStream) error {
|
|||
}
|
||||
|
||||
func (h *TunnelHandler) logError(stream *h2mux.MuxedStream, err error) {
|
||||
Log.WithError(err).Error("HTTP request error")
|
||||
logger.WithError(err).Error("HTTP request error")
|
||||
stream.WriteHeaders([]h2mux.Header{{Name: ":status", Value: "502"}})
|
||||
stream.Write([]byte("502 Bad Gateway"))
|
||||
h.metrics.incrementResponses(h.connectionID, "502")
|
||||
|
@ -509,20 +511,20 @@ func (h *TunnelHandler) logError(stream *h2mux.MuxedStream, err error) {
|
|||
|
||||
func (h *TunnelHandler) logRequest(req *http.Request, cfRay string) {
|
||||
if cfRay != "" {
|
||||
Log.WithField("CF-RAY", cfRay).Infof("%s %s %s", req.Method, req.URL, req.Proto)
|
||||
logger.WithField("CF-RAY", cfRay).Infof("%s %s %s", req.Method, req.URL, req.Proto)
|
||||
} else {
|
||||
Log.Warnf("All requests should have a CF-RAY header. Please open a support ticket with Cloudflare. %s %s %s ", req.Method, req.URL, req.Proto)
|
||||
logger.Warnf("All requests should have a CF-RAY header. Please open a support ticket with Cloudflare. %s %s %s ", req.Method, req.URL, req.Proto)
|
||||
}
|
||||
Log.Debugf("Request Headers %+v", req.Header)
|
||||
logger.Debugf("Request Headers %+v", req.Header)
|
||||
}
|
||||
|
||||
func (h *TunnelHandler) logResponse(r *http.Response, cfRay string) {
|
||||
if cfRay != "" {
|
||||
Log.WithField("CF-RAY", cfRay).Infof("%s", r.Status)
|
||||
logger.WithField("CF-RAY", cfRay).Infof("%s", r.Status)
|
||||
} else {
|
||||
Log.Infof("%s", r.Status)
|
||||
logger.Infof("%s", r.Status)
|
||||
}
|
||||
Log.Debugf("Response Headers %+v", r.Header)
|
||||
logger.Debugf("Response Headers %+v", r.Header)
|
||||
}
|
||||
|
||||
func (h *TunnelHandler) UpdateMetrics(connectionID string) {
|
||||
|
|
|
@ -8,10 +8,12 @@ import (
|
|||
"io/ioutil"
|
||||
"net"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
cli "gopkg.in/urfave/cli.v2"
|
||||
"github.com/cloudflare/cloudflared/log"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
var logger = log.CreateLogger()
|
||||
|
||||
// CLIFlags names the flags used to configure TLS for a command or subsystem.
|
||||
// The nil value for a field means the flag is ignored.
|
||||
type CLIFlags struct {
|
||||
|
@ -29,7 +31,7 @@ func (f CLIFlags) GetConfig(c *cli.Context) *tls.Config {
|
|||
if c.IsSet(f.Cert) && c.IsSet(f.Key) {
|
||||
cert, err := tls.LoadX509KeyPair(c.String(f.Cert), c.String(f.Key))
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Error parsing X509 key pair")
|
||||
logger.WithError(err).Fatal("Error parsing X509 key pair")
|
||||
}
|
||||
config.Certificates = []tls.Certificate{cert}
|
||||
config.BuildNameToCertificate()
|
||||
|
@ -53,11 +55,11 @@ func (f CLIFlags) GetConfig(c *cli.Context) *tls.Config {
|
|||
func LoadCert(certPath string) *x509.CertPool {
|
||||
caCert, err := ioutil.ReadFile(certPath)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("Error reading certificate %s", certPath)
|
||||
logger.WithError(err).Fatalf("Error reading certificate %s", certPath)
|
||||
}
|
||||
ca := x509.NewCertPool()
|
||||
if !ca.AppendCertsFromPEM(caCert) {
|
||||
log.WithError(err).Fatalf("Error parsing certificate %s", certPath)
|
||||
logger.WithError(err).Fatalf("Error parsing certificate %s", certPath)
|
||||
}
|
||||
return ca
|
||||
}
|
||||
|
@ -66,23 +68,23 @@ func LoadOriginCertsPool() *x509.CertPool {
|
|||
// First, obtain the system certificate pool
|
||||
certPool, systemCertPoolErr := x509.SystemCertPool()
|
||||
if systemCertPoolErr != nil {
|
||||
log.Warn("error obtaining the system certificates: %s", systemCertPoolErr)
|
||||
logger.Warnf("error obtaining the system certificates: %s", systemCertPoolErr)
|
||||
certPool = x509.NewCertPool()
|
||||
}
|
||||
|
||||
// Next, append the Cloudflare CA pool into the system pool
|
||||
if !certPool.AppendCertsFromPEM([]byte(cloudflareRootCA)) {
|
||||
log.Warn("could not append the CF certificate to the system certificate pool")
|
||||
logger.Warn("could not append the CF certificate to the system certificate pool")
|
||||
|
||||
if systemCertPoolErr != nil { // Obtaining both certificates failed; this is a fatal error
|
||||
log.WithError(systemCertPoolErr).Fatalf("Error loading the certificate pool")
|
||||
logger.WithError(systemCertPoolErr).Fatalf("Error loading the certificate pool")
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, add the Hello certificate into the pool (since it's self-signed)
|
||||
helloCertificate, err := GetHelloCertificateX509()
|
||||
if err != nil {
|
||||
log.Warn("error obtaining the Hello server certificate")
|
||||
logger.Warn("error obtaining the Hello server certificate")
|
||||
}
|
||||
|
||||
certPool.AddCert(helloCertificate)
|
||||
|
|
|
@ -8,16 +8,18 @@ import (
|
|||
"sync"
|
||||
"syscall"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/log"
|
||||
"github.com/cloudflare/cloudflared/metrics"
|
||||
|
||||
"github.com/coredns/coredns/core/dnsserver"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/cache"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
var logger = log.CreateLogger()
|
||||
|
||||
// Listener is an adapter between CoreDNS server and Warp runnable
|
||||
type Listener struct {
|
||||
server *dnsserver.Server
|
||||
|
@ -28,14 +30,14 @@ type Listener struct {
|
|||
func Run(c *cli.Context) error {
|
||||
metricsListener, err := net.Listen("tcp", c.String("metrics"))
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Failed to open the metrics listener")
|
||||
logger.WithError(err).Fatal("Failed to open the metrics listener")
|
||||
}
|
||||
|
||||
go metrics.ServeMetrics(metricsListener, nil)
|
||||
go metrics.ServeMetrics(metricsListener, nil, logger)
|
||||
|
||||
listener, err := CreateListener(c.String("address"), uint16(c.Uint("port")), c.StringSlice("upstream"))
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("Failed to create the listeners")
|
||||
logger.WithError(err).Errorf("Failed to create the listeners")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -43,7 +45,7 @@ func Run(c *cli.Context) error {
|
|||
readySignal := make(chan struct{})
|
||||
err = listener.Start(readySignal)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("Failed to start the listeners")
|
||||
logger.WithError(err).Errorf("Failed to start the listeners")
|
||||
return listener.Stop()
|
||||
}
|
||||
<-readySignal
|
||||
|
@ -57,7 +59,7 @@ func Run(c *cli.Context) error {
|
|||
// Shut down server
|
||||
err = listener.Stop()
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("failed to stop")
|
||||
logger.WithError(err).Errorf("failed to stop")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -78,7 +80,7 @@ func createConfig(address string, port uint16, p plugin.Handler) *dnsserver.Conf
|
|||
// Start blocks for serving requests
|
||||
func (l *Listener) Start(readySignal chan struct{}) error {
|
||||
defer close(readySignal)
|
||||
log.WithField("addr", l.server.Address()).Infof("Starting DNS over HTTPS proxy server")
|
||||
logger.WithField("addr", l.server.Address()).Infof("Starting DNS over HTTPS proxy server")
|
||||
|
||||
// Start UDP listener
|
||||
if udp, err := l.server.ListenPacket(); err == nil {
|
||||
|
@ -119,7 +121,7 @@ func CreateListener(address string, port uint16, upstreams []string) (*Listener,
|
|||
// Build the list of upstreams
|
||||
upstreamList := make([]Upstream, 0)
|
||||
for _, url := range upstreams {
|
||||
log.WithField("url", url).Infof("Adding DNS upstream")
|
||||
logger.WithField("url", url).Infof("Adding DNS upstream")
|
||||
upstream, err := NewUpstreamHTTPS(url)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create HTTPS upstream")
|
||||
|
|
|
@ -52,7 +52,7 @@ type RegistrationOptions struct {
|
|||
ConnectionID uint8 `capnp:"connectionId"`
|
||||
OriginLocalIP string `capnp:"originLocalIp"`
|
||||
IsAutoupdated bool `capnp:"isAutoupdated"`
|
||||
gracePeriodNanoSec int64 `capnp:"gracePeriodNanoSec"`
|
||||
RunFromTerminal bool `capnp:"runFromTerminal"`
|
||||
}
|
||||
|
||||
func MarshalRegistrationOptions(s tunnelrpc.RegistrationOptions, p *RegistrationOptions) error {
|
||||
|
|
|
@ -37,6 +37,8 @@ struct RegistrationOptions {
|
|||
originLocalIp @7 :Text;
|
||||
# whether Argo Tunnel client has been autoupdated
|
||||
isAutoupdated @8 :Bool;
|
||||
# whether Argo Tunnel client is run from a terminal
|
||||
runFromTerminal @9 :Bool;
|
||||
}
|
||||
|
||||
struct Tag {
|
||||
|
|
|
@ -403,6 +403,14 @@ func (s RegistrationOptions) SetIsAutoupdated(v bool) {
|
|||
s.Struct.SetBit(24, v)
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) RunFromTerminal() bool {
|
||||
return s.Struct.Bit(25)
|
||||
}
|
||||
|
||||
func (s RegistrationOptions) SetRunFromTerminal(v bool) {
|
||||
s.Struct.SetBit(25, v)
|
||||
}
|
||||
|
||||
// RegistrationOptions_List is a list of RegistrationOptions.
|
||||
type RegistrationOptions_List struct{ capnp.List }
|
||||
|
||||
|
@ -1218,86 +1226,88 @@ func (p TunnelServer_unregisterTunnel_Results_Promise) Struct() (TunnelServer_un
|
|||
return TunnelServer_unregisterTunnel_Results{s}, err
|
||||
}
|
||||
|
||||
const schema_db8274f9144abc7e = "x\xda\x9cU_\x88Te\x1b\x7f~\xef;3g\x84" +
|
||||
"]g\x0fg\x04\xbf\xe1\x93\xe5\x93\x15\xff\xe0\xfa\xe9\xa7" +
|
||||
"\xfb\xa1\xdb\x9f\xd9\xdd\xd4\x98m]\xe7\xdd\xd1\x10\xf5\xc2" +
|
||||
"\xe3\xcc\xeb\xec\xd9f\xce\x19\xce9c)\xa4%B " +
|
||||
"$\x96uc\x14\xe4e\x17\x15t\x11\x84\x81\xdd$\xe1" +
|
||||
"\x85\x08\x19EB\x94l\xa1(\xd6\xa2\x90\x91\x9cx\xcf" +
|
||||
"\xec\x999\xae\xa5\xd6\xdd9\xcf\xfb>\xcf\xf3{\xfe\xfc" +
|
||||
"~\xef\xea\x1f\xd9\x10[\x93\xfc.I$6&S\xc1" +
|
||||
"\xe3\xf5\x0b\xa7\xff\xff\xe6\xf9\xa3\xa4\xe7Xp\xe8\xcch" +
|
||||
"\xf6\x8e\x7f\xe4[\"\xac\xbd\xc4\x0e\xc2\xb8\xca4\"c" +
|
||||
"\x9am%\x04\x17V\x9e\xf9\xe4\xc4G\xaf\xbcEb)" +
|
||||
"@\x94\xd0\x88\xd6\xdee\xbf\x81`\xe8<O\x08\xde\xf8" +
|
||||
"\xfa\xd3\xf1\xfak\xa7N\x93\xbe4:\xdf\xc0\x19\xa3D" +
|
||||
"\xb0\xa0\x80\xcbg\xd7$>n\x9d$\xb9:\xea\xe7\xd7" +
|
||||
"\x94\xeb0\xff\x80\x10,\xba1\xd2m\xdf<r\x96\xf4" +
|
||||
"\x1c:(Z\x17\xbf\xe7\xa30n\xabO\xe3\x97\xf0\xf2" +
|
||||
"\xe8\xae\x93\xaf'\xa7O\x9e#\x91C\xfcvJ\xdd~" +
|
||||
"5\xe1\xc2x7L\xfev\"\x00!\xc8}\xf8\xd8\xfb" +
|
||||
"#\x95o\xce\xcf\x89\x1dV\xf6Ej\xc6\xb8\xa4\xfc\x8c" +
|
||||
"\x8b\xa9\xe7\x09\x01\x9b6\xff\xf5\xd2WO^\x8e\x95\xd0" +
|
||||
"\xaf\xfd\x00J\x04\xe3\xcf\xee\x9a\x9a\xf7\xe2\x95+\xb3%" +
|
||||
"@\x1d\xfdG\x0bK\x18\xd0T\xf5\x03{\x86\xe5\xee\xf5" +
|
||||
";\xae\x91\x9e\xe3\xf74r\xbb6\x08Cj*\x89\xa9" +
|
||||
"\x9d3\xae\xaa\xaf\xe0\xf8\xa1\x8d[7,\xfel&\x1e" +
|
||||
"\xee\xa26\xa3\xc2M\x87\xe1\xf6\xad\xbf\xfe\xf4\x92\xe3\x9f" +
|
||||
"\xcf\xccA\x1d^L\xa6W\xc0X\x90V\x11\xf5t\x9e" +
|
||||
"ps\xf3;_\xe62\xb9[s\xfa\x11vo =" +
|
||||
"\x05\xa3\x10\xde\xdd\x94\xfe\x89\xfa\x03\xbfi\xdb\xb2\xe66" +
|
||||
"\x12\xe5\xffF\x9f\xe5Ue\xb3a7\x067\xbd`y" +
|
||||
"\xbeeW\xb7\x85\xf6|\xd1\xa9Y\xe5\x03E@t\x81" +
|
||||
"\x11\xe9\x8b\x06\x89\x00}\xc1N\"0]\x1f!\xca[" +
|
||||
"U\xdbqeP\xb1\xbc\xb2c\xdb\x92x\xd9?\xbc\xd7" +
|
||||
"\xac\x99vY\xb6\x13\xa5\xeeO\xd4JP\x92\xee~\xe9" +
|
||||
"\xaej\xda\xae\xacZ\x9e/\xdd\x96\xb9/_4]\xb3" +
|
||||
"\xee\x89\x04O\x10%@\xa4w\x9f\"\x12=\x1c\xe2\xdf" +
|
||||
"\x0cA\xd55\xcb\xb2(]XNe\xdc\xb4\x9d\x12\x97" +
|
||||
"e$\x89!Ih'\x9d\xffw\x93NH\xafY\xf3" +
|
||||
"=j{=\xd8\x7f\x8ew\xd1\xcc\x84\x90\xbb\xda\x907" +
|
||||
"\xedT\x04\xe3\x10E\x06\x1d\xc8*\xca\xe8[F\x89\xc4" +
|
||||
"\x18\x87\xd8\xc1\xa03\x96\x0d\xdb\xba}\x84H\x149\xc4" +
|
||||
"n\x86\xc0q\xad\xaae?%\x89\xbb>\xba\x89\xa1\x9b" +
|
||||
"\x10L:\x9eo\x9buID\xe8\"\x86.\xc2a\xa7" +
|
||||
"\xe1[\x8e\xed\xa1\xa7C\x07\x02zb-\xf8\x93\x01\x0f" +
|
||||
"7\xfdIi\xfbV\xd9T\xceD\xe1l;\x90\x17\x13" +
|
||||
"\x89!\x0e1\x16\x83\\\xf8_\xac\x8e\x08\xf2\x96\xbd\x9d" +
|
||||
":\xb4\xe7\xe4\x81\x08U\xaf\xac\x9bV-\xfa\x8b\x8a\x19" +
|
||||
"&\xed\x99\xce\x9d\x07\xe1\x9b\x08\xbb\xea\x86\xe8\xb66z" +
|
||||
"\xc3\x0a\x15\xc6\xbe6\xc6\x1b\xaa\x83\xd79\xc4\xaf1\x8c" +
|
||||
"\xb7U\x07\x7f\xe6\x10\xbf\xc70\xde\xc9\x11\x89[\x1c\x13" +
|
||||
"`\x00\xcf\x82\x13\xe9w\xdf#\x9a\x00G\xa9\x0b\x0cz" +
|
||||
"\x82g\x91 2\xe6a\x94\xa8\x94V\xf6\xac\xb2'\x13" +
|
||||
"Y$\x15\xb7\xb0\x82\xa8\xd4\xa5\xec\xcb\x94=\xc5\xb2H" +
|
||||
"\x11\x19K0ET\xeaS\xf6\xd5\xca\xae%\xb3\x8a\x96" +
|
||||
"F?\\\xa2\xd2Je_\xaf\xec\xe9\x85Y\xa4\x89\x8c" +
|
||||
"\x81\xd0\xbeN\xd9\x87\xc0\x10\x94k\x96\xb4\xfdB%>" +
|
||||
"\xce\xfd\xd2\xf5,\xc7\x8e\xfe\xb9\xe3\xb5\xfb%gY\x89" +
|
||||
"\xd6\xae\x15\x9d\x8c\xa2%2\x1d\xe9& C\x08\x1a\x8e" +
|
||||
"S\x1b\xbfwM2\xbeY\xf50\x9fP\xe4@OG" +
|
||||
"\x0a\x09\xca\x18\x84\xa4-\xfb\x16e\x1c\xbbPA\x8a\x18" +
|
||||
"R\xed\xb9\x8d9\xd4[6k\x85F\x1b\x89\xe5\x0d7" +
|
||||
"}\xa7\xd9\xa0\xde\x8a\xe9\xcb\x0a@\x0c\x88M\x94\xcd\x9d" +
|
||||
"hocp\x9bYU\x13L\xb7'\xb8|\x05\x91\xe8" +
|
||||
"\xe3\x10\xabc\x13\xecW[\xb6\x8cC\xacc\xc8\xa8U" +
|
||||
"oo\xd4~\xb3\xd6\x94\xf7\xed\xce\xc34\xa5*\xfd\xd6" +
|
||||
"W\xc1\xde\xe7\xf4\x15MW3\xeb\xde?\xf4\x9e\x90^" +
|
||||
"FIC\\\x8f\x06\x89D\x9aCd\x19\xf2n\xa8\x1c" +
|
||||
"\xe8\xe9H\xf6\x1c\"\xf2\xbfJ\x97oei\xb10I" +
|
||||
"\xd4~'\x11=\x0f\xba8HL/h\xe8<M\x88" +
|
||||
"^\"\xfd\x09\x97\x98>\xa0\x81\xb5\x9ffDO\xb0\xbe" +
|
||||
"\xfc\x181}\x89\x16D:E\xf9V\xca!\x04Qu" +
|
||||
"\xd4\x1b\xd67\x84 \x12CDzF4\x84\"\x1e\xbd" +
|
||||
"\xdd\xf7ii\xaf\xf7(\x1d\x8b\xde\xad\x87\xf7\xab\x95'" +
|
||||
"\xa3\xf0\xaan\xc5\xe2N\x11\x89.\x0e\xb1\x90!\xa89" +
|
||||
"\xb3\xc2\x96\x19\x8f\xad\xd0\x83\x04\xa7\x058\x92\x9d\x8cr" +
|
||||
"V\xf1{\xda\xf1M\xa5\x89\xbb9\xc4dl[\xa52" +
|
||||
"\xee\xe1\x10\xb5\x98\xdeXJ\x99&9\xc4\xd1\x8e\xde\xbc" +
|
||||
"|\x8cH\x1c\xe5\x10'\x184\xe9\xba\x11$\xad\xe9v" +
|
||||
"T\xb2\xe6T\xc7,[z\x8a\xb6\xb3LUG\x8a\x9f" +
|
||||
"\x0d\xe9\xd6M[\xda\xf07\x9bV\xad\xe9J\xb5Z-" +
|
||||
"\xd2\xfd\x11\x00\x00\xff\xffy%\x9bh"
|
||||
const schema_db8274f9144abc7e = "x\xda\x9cU_l\x14U\x17\xff\x9d{w;\xdb\xa4" +
|
||||
"e;\x99m\x02\x1bH\x13\xd2\x86B\xbe\xf2\xc1\xc7\x87" +
|
||||
"B\xfd\xd3?\x02\xba\xb5\x94\xbdl1\x08}`\xd8\xbd" +
|
||||
"l\xa7\xce\xcelffQH\x04%\x18#\x89\x04E" +
|
||||
"^0\x9a@\xe2\x8b\x0fj\xe2\x83\x89\xc1\x04_\xe4\x81" +
|
||||
"\x07^\xd4h$1J\x88\x91h\x88\x8d\x9ahb\xc6" +
|
||||
"\xdc\xd9\xce\xecR\x14\xd0\xb7\x99\xdf=\xf7\x9c\xdf9\xf7" +
|
||||
"\x9c\xdfY\xf7+\x1be\xeb\xd3_\xa7\x01\xb1%\xdd\x11" +
|
||||
">X\xbbr\xfe\xbe3\x97\x8fC\xcf\xb3\xf0\xc8\x85\x89" +
|
||||
"\xdco\xc1\xb1\xaf\x00\xda\xf0\x19;L\xc6\xf7L\x03\x8c" +
|
||||
"\xebl\x07(\xbc\xf2\x9f\x0b\x1f\x9ez\xff\xc5\xd7!V" +
|
||||
"\x11\x01)\x0d\xd8\xf0\x07\xfb\x9d@\x86\xceG@\xe1k" +
|
||||
"_|4U{\xe5\xecy\xe8\xab\xe2\xf3\xcd\x9c1\xa4" +
|
||||
"\xc2\xde\x02]\xbd\xb8>\xf5A\xf3$\xcd\xd5\xd1\x10\xbf" +
|
||||
"\xa1\xae\x8e\xf1wA\xe1\x8a\x1f\xc7\xbb\x9d\x9b\xc7.B" +
|
||||
"\xcfS\x8bE\xd3\xf0\x1b>A\xc6/\xea\xd3\xf8)2" +
|
||||
"\x9e\xd8{\xfa\xd5\xf4\xf5\xd3\x97 \xf2\xd4n\xdd\xa1\xac" +
|
||||
"_Nyd\x9c\x8b\x82\xbf\x91\xba\x9f\x81\xc2\xfc{\x0f" +
|
||||
"\xbc3^\xf9\xf2\xf2\"\xdfQf\x9d\xda\xbc\xd1\xab\xa9" +
|
||||
"/]{\x1a\x14\xb2\xeb\xe6\xb2\xe7>\x7f\xf8j[\x0a" +
|
||||
"5\xed[B*\x9czb\xef\\\xe7\xb3\xd7\xae-\xa4" +
|
||||
"@\xea\xc8\xd4\xa2\x14\x1a\x9a\xca~\xe3\xbe19\xb3i" +
|
||||
"\xf7\x0d\xe8y~K!\xcfh\xc3d\xbc\x15\x059\xa7" +
|
||||
"]2Vg4 <yd\xcb\x8e\xcd+?\x9eo" +
|
||||
"w\xa7g\xe6\x95\xbb\x81\x8crw`\xd3\x0f\x8f\x0e\x9c" +
|
||||
"\xfcd~\x11\xeb\xc8pkf\x0d\x19\xbb\x94\x1fC(" +
|
||||
"\xe3\x9b\xdb\xde\xfc4\x9f\xcd\xff\xbc\xa8\x1eQ\xf5\x1a\x99" +
|
||||
"92^\x8al_\xc8|\x87\xa10h8\x8e\xb4\xbd" +
|
||||
"z\xaa\xfc\xdf\xf8\xb3\xbc\xb6l\xd6\x9d\xfa\xf0\xd6g," +
|
||||
"?\xb0\x9c\xeat\x84\x8f\x14]\xdb*\x1f*\x12\x89." +
|
||||
"b\x80\xbeb\x18 \xd2{\xf7\x00\xc4t}\x1c\x18\xb1" +
|
||||
"\xaa\x8e\xeb\xc9\xb0b\xf9e\xd7q$x98\xba\xdf" +
|
||||
"\xb4M\xa7,\x93@\x1d\xb7\x07j\x06(I\xef\xa0\xf4" +
|
||||
"\xd66\x1cOV-?\x90^\x13\xee\x1f)\x9a\x9eY" +
|
||||
"\xf3E\x8a\xa7\x80\x14\x01z\xf7Y@\xf4p\x12\xcb\x19" +
|
||||
"\x85U\xcf,\xcb\xa2\xf4\xc8r+S\xa6\xe3\x96\xb8," +
|
||||
"S\x1a\x8c\xd2\xa0$\xe8\x92\x7f\x1at\xa7\xf4\x1bv\xe0" +
|
||||
"#\xb9u\xe7\xfb\x8bn\x17\xcdlD\xb9+\xa1\xbcu" +
|
||||
"\x8f\x1a0N\xa2\xc8H'\xca\xa9\x91\xd1\xb7O\x00b" +
|
||||
"\x92\x93\xd8\xcdHg,\x17\x95u\xd78 \x8a\x9c\xc4" +
|
||||
"\x0c\xa3\xd0\xf5\xac\xaa\xe5<\"\xc1\xbd\x80\xba\xc1\xa8\x1b" +
|
||||
"\x14\xce\xba~\xe0\x985\x09\x80\xba\xc0\xa8\x0bt\xd4\xad" +
|
||||
"\x07\x96\xeb\xf8\xd4\xd3\x1a\x07\x10\xf5\xb4\x95\xe0/\x1ex" +
|
||||
"\xac\x11\xccJ'\xb0\xca\xa6\xba\x0cDo\xdb\xa2\xbc\x12" +
|
||||
"\x10\xa3\x9c\xc4d\x1b\xe5\xc2\xff\xda\xf2\x88)o\xdf\xdf" +
|
||||
"\xcaC{J\x1e\x8aY\xf5\xc9\x9ai\xd9\xf1_\x9c\xcc" +
|
||||
"\x18\xb4\xc7[6w\xe2\xb73\xaa\xaa\x17\xb1\xdbQ\xef" +
|
||||
"\x8b2T\x1c\x07c\x8eF'M\x00\xa5\x0cq*\xe5" +
|
||||
"\xa8E\xd3\xd0i\x1c(u)|)\xb5\x98\x1a\xbd\x94" +
|
||||
"\x07J=\x0a_N\x8c\x88\xe7\x88\x03\xc62z\x1b(" +
|
||||
"-W\xf0\xa02O\xf1\x1c\xa5\x00c r\xdf\xaf\xf0" +
|
||||
"u\x0aO\xa7r\x94\x06\x8c!Z\x03\x94\x06\x15\xbeE" +
|
||||
"\xe1\x1d,G\x1d\x801Fs@iT\xe1\x93\x0a\xd7" +
|
||||
"\xd295\xa1F\x81<\xa0\xf4\x98\xc2\xa7\x15\x9eY\x9a" +
|
||||
"\xa3\x8c\x1a\xd7\x08/*|F\xe1\x9d\xcbr\xd4\x09\x18" +
|
||||
"O\xd21\xa0\xb4[\xe1\x15b\x14\x96mK:A\xa1" +
|
||||
"\xd2\xfe\xe2\x07\xa5\xe7[\xae\x13\xffs\xd7OJ*\x17" +
|
||||
"\x06\x97\x9a\xedXt\xb3jr)\xdbRw\x10eA" +
|
||||
"a\xddu\xed\xa9[;)\x1b\x98U\x9f\x96\x80\x8a\x9c" +
|
||||
"\xa8\xa7\xa5\x96 \x05\x86\xd1\\\x97\x03\x0bY\xd7)T" +
|
||||
"\xa8\x03\x8c:\x92\xa7\x9dt\xd1W6\xedB=ab" +
|
||||
"\xf9c\x8d\xc0m\xd4\xd1W1\x03Y!\x02#\x02\x85" +
|
||||
"^\xc3\xd9\xe6\xb9\xb5i\x92^\xcdrL\x1b\xc9I\xdc" +
|
||||
"\x03lq;\xf4\xd5\x87\xa7\xcd\xaaz\xfeL\xd2\xa2\xab" +
|
||||
"\xd7\x00\xa2\x9f\x93X\xd7\xd6\xa2C\xaaE\x079\x89\xff" +
|
||||
"3\xca\xaa9I\xda\xf1\xa0i7\xe4m\x8dw7A" +
|
||||
"\xaa\xca\xa0\xf9Up\x0e\xb8\xfdE\xd3\xd3\xcc\x9a\xff/" +
|
||||
"o\xef\x94~V\xe9J\xbb\x98\x0d\x03\"\xc3I\xe4\x18" +
|
||||
"\x8dx\x91\xecPOK\xef\x17M1\xff\xbbp#\xcd" +
|
||||
"(\xcd\x11N\x03\xc9\x92\xa5x\xb7\xe8\xe20\x98^\xd0" +
|
||||
"\xa8\xb5\xd7(^c\xfaC\x1e\x98\xbeQ#\x96\xecu" +
|
||||
"\x8a\xf7\xb7\xbe\xfa\x04\x98>\xa0\x85\xb1\xc8a\xa4\x19r" +
|
||||
"\x94\xc28;\xf4E\xf9\x8dR\x18+)\xc5b\x08\x8c" +
|
||||
"R\x91\xee\xbd\xdc\xb7\x09q\x9f\x7f/\x15\x8b\x97\xde\xdd" +
|
||||
"\xeb\xd5\x8c\x93U|U\xb5\xda\xfc\xce\x01\xa2\x8b\x93X" +
|
||||
"\xca(\xb4\xdd\x05U\xccN\xb5\xb5\xd0\x9d\xd4\xaaI8" +
|
||||
"\xd6\xac\xac\xba\xac\xfc\xf7$\xfeM%\xa83\x9c\xc4l" +
|
||||
"[\xb7J\x05\xee\xe3$\xec6A\xb5\xd4b\x98\xe5$" +
|
||||
"\x8e'\x1a\xa5?\x7f\x02\x10\xc79\x89S\x8c4\xe9y" +
|
||||
"1%\xad\xe1\xb5$\xd6v\xab\x93\x96#}5\xd0\x0b" +
|
||||
"3\xac\x8e\xd4\xe4\xd6\xa5W3\x1d\xe9P\xb0\xcd\xb4\xec" +
|
||||
"\x86'\x91\x0c\xdd\x9f\x01\x00\x00\xff\xffR3\x9d#"
|
||||
|
||||
func init() {
|
||||
schemas.Register(schema_db8274f9144abc7e,
|
||||
|
|
Loading…
Reference in New Issue