Write tunnel token to EnvironmentFile, resolve #802
This commit is contained in:
parent
9b8a533435
commit
faa43cde1c
|
@ -8,23 +8,25 @@ import (
|
||||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel"
|
"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel"
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildArgsForToken(c *cli.Context, log *zerolog.Logger) ([]string, error) {
|
type buildArgsFunc = func(c *cli.Context, log *zerolog.Logger) ([]string, map[string]string, error)
|
||||||
|
|
||||||
|
func buildArgsForToken(c *cli.Context, log *zerolog.Logger) ([]string, map[string]string, error) {
|
||||||
token := c.Args().First()
|
token := c.Args().First()
|
||||||
if _, err := tunnel.ParseToken(token); err != nil {
|
if _, err := tunnel.ParseToken(token); err != nil {
|
||||||
return nil, cliutil.UsageError("Provided tunnel token is not valid (%s).", err)
|
return nil, nil, cliutil.UsageError("Provided tunnel token is not valid (%s).", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{
|
return []string{"tunnel", "run"},
|
||||||
"tunnel", "run", "--token", token,
|
map[string]string{"TUNNEL_TOKEN": token},
|
||||||
}, nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getServiceExtraArgsFromCliArgs(c *cli.Context, log *zerolog.Logger) ([]string, error) {
|
func getServiceExtraArgsFromCliArgs(c *cli.Context, log *zerolog.Logger) ([]string, map[string]string, error) {
|
||||||
if c.NArg() > 0 {
|
if c.NArg() > 0 {
|
||||||
// currently, we only support extra args for token
|
// currently, we only support extra args for token
|
||||||
return buildArgsForToken(c, log)
|
return buildArgsForToken(c, log)
|
||||||
} else {
|
} else {
|
||||||
// empty extra args
|
// empty extra args
|
||||||
return make([]string, 0), nil
|
return make([]string, 0), nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ const (
|
||||||
serviceConfigFile = "config.yml"
|
serviceConfigFile = "config.yml"
|
||||||
serviceCredentialFile = "cert.pem"
|
serviceCredentialFile = "cert.pem"
|
||||||
serviceConfigPath = serviceConfigDir + "/" + serviceConfigFile
|
serviceConfigPath = serviceConfigDir + "/" + serviceConfigFile
|
||||||
|
serviceEnvFile = "/etc/default/cloudflared"
|
||||||
cloudflaredService = "cloudflared.service"
|
cloudflaredService = "cloudflared.service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,6 +57,8 @@ After=network.target
|
||||||
[Service]
|
[Service]
|
||||||
TimeoutStartSec=0
|
TimeoutStartSec=0
|
||||||
Type=notify
|
Type=notify
|
||||||
|
{{- if ne .EnvFile "" }}
|
||||||
|
EnvironmentFile=-{{ .EnvFile }}{{ end }}
|
||||||
ExecStart={{ .Path }} --no-autoupdate{{ range .ExtraArgs }} {{ . }}{{ end }}
|
ExecStart={{ .Path }} --no-autoupdate{{ range .ExtraArgs }} {{ . }}{{ end }}
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
|
@ -196,19 +199,23 @@ func installLinuxService(c *cli.Context) error {
|
||||||
Path: etPath,
|
Path: etPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraArgsFunc func(c *cli.Context, log *zerolog.Logger) ([]string, error)
|
var extraArgsFunc buildArgsFunc
|
||||||
if c.NArg() == 0 {
|
if c.NArg() == 0 {
|
||||||
extraArgsFunc = buildArgsForConfig
|
extraArgsFunc = buildArgsForConfig
|
||||||
} else {
|
} else {
|
||||||
extraArgsFunc = buildArgsForToken
|
extraArgsFunc = buildArgsForToken
|
||||||
}
|
}
|
||||||
|
|
||||||
extraArgs, err := extraArgsFunc(c, log)
|
extraArgs, extraEnv, err := extraArgsFunc(c, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
templateArgs.ExtraArgs = extraArgs
|
templateArgs.ExtraArgs = extraArgs
|
||||||
|
templateArgs.Env = extraEnv
|
||||||
|
if len(extraEnv) > 0 {
|
||||||
|
templateArgs.EnvFile = serviceEnvFile
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case isSystemd():
|
case isSystemd():
|
||||||
|
@ -225,14 +232,14 @@ func installLinuxService(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildArgsForConfig(c *cli.Context, log *zerolog.Logger) ([]string, error) {
|
func buildArgsForConfig(c *cli.Context, log *zerolog.Logger) ([]string, map[string]string, error) {
|
||||||
if err := ensureConfigDirExists(serviceConfigDir); err != nil {
|
if err := ensureConfigDirExists(serviceConfigDir); err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
src, _, err := config.ReadConfigFile(c, log)
|
src, _, err := config.ReadConfigFile(c, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't use context because this command doesn't define "credentials-file" flag
|
// can't use context because this command doesn't define "credentials-file" flag
|
||||||
|
@ -241,24 +248,24 @@ func buildArgsForConfig(c *cli.Context, log *zerolog.Logger) ([]string, error) {
|
||||||
return err == nil && val != ""
|
return err == nil && val != ""
|
||||||
}
|
}
|
||||||
if src.TunnelID == "" || !configPresent(tunnel.CredFileFlag) {
|
if src.TunnelID == "" || !configPresent(tunnel.CredFileFlag) {
|
||||||
return nil, fmt.Errorf(`Configuration file %s must contain entries for the tunnel to run and its associated credentials:
|
return nil, nil, fmt.Errorf(`Configuration file %s must contain entries for the tunnel to run and its associated credentials:
|
||||||
tunnel: TUNNEL-UUID
|
tunnel: TUNNEL-UUID
|
||||||
credentials-file: CREDENTIALS-FILE
|
credentials-file: CREDENTIALS-FILE
|
||||||
`, src.Source())
|
`, src.Source())
|
||||||
}
|
}
|
||||||
if src.Source() != serviceConfigPath {
|
if src.Source() != serviceConfigPath {
|
||||||
if exists, err := config.FileExists(serviceConfigPath); err != nil || exists {
|
if exists, err := config.FileExists(serviceConfigPath); err != nil || exists {
|
||||||
return nil, fmt.Errorf("Possible conflicting configuration in %[1]s and %[2]s. Either remove %[2]s or run `cloudflared --config %[2]s service install`", src.Source(), serviceConfigPath)
|
return nil, nil, fmt.Errorf("Possible conflicting configuration in %[1]s and %[2]s. Either remove %[2]s or run `cloudflared --config %[2]s service install`", src.Source(), serviceConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := copyFile(src.Source(), serviceConfigPath); err != nil {
|
if err := copyFile(src.Source(), serviceConfigPath); err != nil {
|
||||||
return nil, fmt.Errorf("failed to copy %s to %s: %w", src.Source(), serviceConfigPath, err)
|
return nil, nil, fmt.Errorf("failed to copy %s to %s: %w", src.Source(), serviceConfigPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{
|
return []string{
|
||||||
"--config", "/etc/cloudflared/config.yml", "tunnel", "run",
|
"--config", "/etc/cloudflared/config.yml", "tunnel", "run",
|
||||||
}, nil
|
}, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func installSystemd(templateArgs *ServiceTemplateArgs, log *zerolog.Logger) error {
|
func installSystemd(templateArgs *ServiceTemplateArgs, log *zerolog.Logger) error {
|
||||||
|
|
|
@ -25,14 +25,48 @@ type ServiceTemplate struct {
|
||||||
type ServiceTemplateArgs struct {
|
type ServiceTemplateArgs struct {
|
||||||
Path string
|
Path string
|
||||||
ExtraArgs []string
|
ExtraArgs []string
|
||||||
|
EnvFile string
|
||||||
|
Env map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolvePath(s string) (string, error) {
|
||||||
|
resolvedPath, err := homedir.Expand(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error resolving path %s: %v", s, err)
|
||||||
|
}
|
||||||
|
return resolvedPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ServiceTemplate) ResolvePath() (string, error) {
|
func (st *ServiceTemplate) ResolvePath() (string, error) {
|
||||||
resolvedPath, err := homedir.Expand(st.Path)
|
return resolvePath(st.Path)
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error resolving path %s: %v", st.Path, err)
|
|
||||||
}
|
}
|
||||||
return resolvedPath, nil
|
|
||||||
|
func (st *ServiceTemplate) GenerateEnvFile(args *ServiceTemplateArgs) error {
|
||||||
|
if args.EnvFile == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
filePath, err := resolvePath(args.EnvFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = os.Stat(filePath); err == nil {
|
||||||
|
return fmt.Errorf("%s", serviceAlreadyExistsWarn(filePath))
|
||||||
|
}
|
||||||
|
fileMode := os.FileMode(0o640)
|
||||||
|
if st.FileMode != 0 {
|
||||||
|
fileMode &= st.FileMode
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
for k, v := range args.Env {
|
||||||
|
if _, err = fmt.Fprintf(buf, "%s=%s\n", k, v); err != nil {
|
||||||
|
return fmt.Errorf("error writing internal buffer: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = os.WriteFile(filePath, buf.Bytes(), fileMode); err != nil {
|
||||||
|
_ = os.Remove(filePath)
|
||||||
|
return fmt.Errorf("error writing %s: %v", filePath, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {
|
func (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {
|
||||||
|
@ -45,7 +79,11 @@ func (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err = os.Stat(resolvedPath); err == nil {
|
if _, err = os.Stat(resolvedPath); err == nil {
|
||||||
return fmt.Errorf(serviceAlreadyExistsWarn(resolvedPath))
|
return fmt.Errorf("%s", serviceAlreadyExistsWarn(resolvedPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = st.GenerateEnvFile(args); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
Loading…
Reference in New Issue