diff --git a/cmd/cloudflared/config/configuration.go b/cmd/cloudflared/config/configuration.go index b3aef0b0..95b6e814 100644 --- a/cmd/cloudflared/config/configuration.go +++ b/cmd/cloudflared/config/configuration.go @@ -10,13 +10,16 @@ import ( ) var ( - defaultConfigFiles = []string{"config.yml", "config.yaml"} + // File names from which we attempt to read configuration. + DefaultConfigFiles = []string{"config.yml", "config.yaml"} // Launchd doesn't set root env variables, so there is default // Windows default config dir was ~/cloudflare-warp in documentation; let's keep it compatible DefaultConfigDirs = []string{"~/.cloudflared", "~/.cloudflare-warp", "~/cloudflare-warp", "/usr/local/etc/cloudflared", "/etc/cloudflared"} ) +const DefaultCredentialFile = "cert.pem" + // FileExists checks to see if a file exist at the provided path. func FileExists(path string) (bool, error) { f, err := os.Open(path) @@ -40,11 +43,11 @@ func FindInputSourceContext(context *cli.Context) (altsrc.InputSourceContext, er } // FindDefaultConfigPath returns the first path that contains a config file. -// If none of the combination of defaultConfigDirs (differs by OS for legacy reasons) -// and defaultConfigFiles contains a config file, return empty string. +// If none of the combination of DefaultConfigDirs and DefaultConfigFiles +// contains a config file, return empty string. func FindDefaultConfigPath() string { for _, configDir := range DefaultConfigDirs { - for _, configFile := range defaultConfigFiles { + for _, configFile := range DefaultConfigFiles { dirPath, err := homedir.Expand(configDir) if err != nil { continue diff --git a/cmd/cloudflared/linux_service.go b/cmd/cloudflared/linux_service.go index 77175994..b7266dd8 100644 --- a/cmd/cloudflared/linux_service.go +++ b/cmd/cloudflared/linux_service.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "github.com/cloudflare/cloudflared/cmd/cloudflared/config" cli "gopkg.in/urfave/cli.v2" ) @@ -30,12 +31,14 @@ func runApp(app *cli.App, shutdownC, graceShutdownC chan struct{}) { app.Run(os.Args) } +// The directory and files that are used by the service. +// These are hard-coded in the templates below. const ( serviceConfigDir = "/etc/cloudflared" - defaultCredentialFile = "cert.pem" + serviceConfigFile = "config.yml" + serviceCredentialFile = "cert.pem" ) -var defaultConfigFiles = []string{"config.yml", "config.yaml"} var systemdTemplates = []ServiceTemplate{ { Path: "/etc/systemd/system/cloudflared.service", @@ -178,6 +181,23 @@ func isSystemd() bool { return false } +func copyUserConfiguration(userConfigDir, userConfigFile, userCredentialFile string) error { + if err := ensureConfigDirExists(serviceConfigDir); err != nil { + return err + } + srcCredentialPath := filepath.Join(userConfigDir, userCredentialFile) + destCredentialPath := filepath.Join(serviceConfigDir, serviceCredentialFile) + if err := copyCredential(srcCredentialPath, destCredentialPath); err != nil { + return err + } + srcConfigPath := filepath.Join(userConfigDir, userConfigFile) + destConfigPath := filepath.Join(serviceConfigDir, serviceConfigFile) + if err := copyConfig(srcConfigPath, destConfigPath); err != nil { + return err + } + return nil +} + func installLinuxService(c *cli.Context) error { etPath, err := os.Executable() if err != nil { @@ -185,11 +205,12 @@ func installLinuxService(c *cli.Context) error { } templateArgs := ServiceTemplateArgs{Path: etPath} - defaultConfigDir := filepath.Dir(c.String("config")) - defaultConfigFile := filepath.Base(c.String("config")) - if err = copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defaultCredentialFile); err != nil { + userConfigDir := filepath.Dir(c.String("config")) + userConfigFile := filepath.Base(c.String("config")) + userCredentialFile := config.DefaultCredentialFile + if err = copyUserConfiguration(userConfigDir, userConfigFile, userCredentialFile); err != nil { logger.WithError(err).Infof("Failed to copy user configuration. Before running the service, ensure that %s contains two files, %s and %s", - serviceConfigDir, defaultCredentialFile, defaultConfigFiles[0]) + serviceConfigDir, serviceCredentialFile, serviceConfigFile) return err } diff --git a/cmd/cloudflared/service_template.go b/cmd/cloudflared/service_template.go index 6c1e58c1..816fe85d 100644 --- a/cmd/cloudflared/service_template.go +++ b/cmd/cloudflared/service_template.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "os" "os/exec" - "path/filepath" "text/template" "github.com/cloudflare/cloudflared/cmd/cloudflared/config" @@ -120,8 +119,7 @@ func openFile(path string, create bool) (file *os.File, exists bool, err error) return file, false, err } -func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error { - destCredentialPath := filepath.Join(destConfigDir, credentialFile) +func copyCredential(srcCredentialPath, destCredentialPath string) error { destFile, exists, err := openFile(destCredentialPath, true) if err != nil { return err @@ -131,7 +129,6 @@ func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error { } defer destFile.Close() - srcCredentialPath := filepath.Join(srcConfigDir, credentialFile) srcFile, _, err := openFile(srcCredentialPath, false) if err != nil { return err @@ -147,17 +144,8 @@ func copyCertificate(srcConfigDir, destConfigDir, credentialFile string) error { return nil } -func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defaultCredentialFile string) error { - if err := ensureConfigDirExists(serviceConfigDir); err != nil { - return err - } - - if err := copyCertificate(defaultConfigDir, serviceConfigDir, defaultCredentialFile); err != nil { - return err - } - +func copyConfig(srcConfigPath, destConfigPath string) error { // Copy or create config - destConfigPath := filepath.Join(serviceConfigDir, defaultConfigFile) destFile, exists, err := openFile(destConfigPath, true) if err != nil { logger.WithError(err).Infof("cannot open %s", destConfigPath) @@ -168,7 +156,6 @@ func copyCredentials(serviceConfigDir, defaultConfigDir, defaultConfigFile, defa } defer destFile.Close() - srcConfigPath := filepath.Join(defaultConfigDir, defaultConfigFile) srcFile, _, err := openFile(srcConfigPath, false) if err != nil { fmt.Println("Your service needs a config file that at least specifies the hostname option.") diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index f89501b8..63b88aba 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -123,7 +123,7 @@ func Commands() []*cli.Command { }, Before: func(c *cli.Context) error { if c.String("config") == "" { - logger.Warnf("Cannot determine default configuration path. No file %v in %v", defaultConfigFiles, config.DefaultConfigDirs) + logger.Warnf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs) } inputSource, err := config.FindInputSourceContext(c) if err != nil { @@ -211,7 +211,7 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan dnsReadySignal := make(chan struct{}) if c.String("config") == "" { - logger.Warnf("Cannot determine default configuration path. No file %v in %v", defaultConfigFiles, config.DefaultConfigDirs) + logger.Warnf("Cannot determine default configuration path. No file %v in %v", config.DefaultConfigFiles, config.DefaultConfigDirs) } if err := configMainLogger(c); err != nil { diff --git a/cmd/cloudflared/tunnel/configuration.go b/cmd/cloudflared/tunnel/configuration.go index 961e55c2..03759e5c 100644 --- a/cmd/cloudflared/tunnel/configuration.go +++ b/cmd/cloudflared/tunnel/configuration.go @@ -30,20 +30,17 @@ import ( ) var ( - defaultConfigFiles = []string{"config.yml", "config.yaml"} - developerPortal = "https://developers.cloudflare.com/argo-tunnel" - quickStartUrl = developerPortal + "/quickstart/quickstart/" - serviceUrl = developerPortal + "/reference/service/" - argumentsUrl = developerPortal + "/reference/arguments/" + developerPortal = "https://developers.cloudflare.com/argo-tunnel" + quickStartUrl = developerPortal + "/quickstart/quickstart/" + serviceUrl = developerPortal + "/reference/service/" + argumentsUrl = developerPortal + "/reference/arguments/" ) -const defaultCredentialFile = "cert.pem" - -// returns the first path that contains a cert.pem file. If none of the defaultConfigDirs -// (differs by OS for legacy reasons) contains a cert.pem file, return empty string +// returns the first path that contains a cert.pem file. If none of the DefaultConfigDirs +// contains a cert.pem file, return empty string func findDefaultOriginCertPath() string { for _, defaultConfigDir := range config.DefaultConfigDirs { - originCertPath, _ := homedir.Expand(filepath.Join(defaultConfigDir, defaultCredentialFile)) + originCertPath, _ := homedir.Expand(filepath.Join(defaultConfigDir, config.DefaultCredentialFile)) if ok, _ := config.FileExists(originCertPath); ok { return originCertPath } @@ -111,7 +108,7 @@ func dnsProxyStandAlone(c *cli.Context) bool { func getOriginCert(c *cli.Context) ([]byte, error) { if c.String("origincert") == "" { - logger.Warnf("Cannot determine default origin certificate path. No file %s in %v", defaultCredentialFile, config.DefaultConfigDirs) + logger.Warnf("Cannot determine default origin certificate path. No file %s in %v", config.DefaultCredentialFile, config.DefaultConfigDirs) if isRunningFromTerminal() { logger.Errorf("You need to specify the origin certificate path with --origincert option, or set TUNNEL_ORIGIN_CERT environment variable. See %s for more information.", argumentsUrl) return nil, fmt.Errorf("Client didn't specify origincert path when running from terminal") diff --git a/cmd/cloudflared/tunnel/login.go b/cmd/cloudflared/tunnel/login.go index f3e96f78..d2d4ec5a 100644 --- a/cmd/cloudflared/tunnel/login.go +++ b/cmd/cloudflared/tunnel/login.go @@ -56,7 +56,7 @@ func checkForExistingCert() (string, bool, error) { if err != nil { return "", false, err } - path := filepath.Join(configPath, defaultCredentialFile) + path := filepath.Join(configPath, config.DefaultCredentialFile) fileInfo, err := os.Stat(path) if err == nil && fileInfo.Size() > 0 { return path, true, nil