Skip to content

Commit 6968b71

Browse files
committed
Add support for taking named tunnel credentials from an environment variable
1 parent 1cb2281 commit 6968b71

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

cmd/cloudflared/tunnel/subcommand_context.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,16 @@ func (sc *subcommandContext) delete(tunnelIDs []uuid.UUID) error {
261261
// and add the TunnelID into any old credentials (generated before TUN-3581 added the `TunnelID`
262262
// field to credentials files)
263263
func (sc *subcommandContext) findCredentials(tunnelID uuid.UUID) (connection.Credentials, error) {
264-
credFinder := sc.credentialFinder(tunnelID)
265-
credentials, err := sc.readTunnelCredentials(credFinder)
264+
var credentials connection.Credentials
265+
var err error
266+
if credentialsContents := sc.c.String(CredContentsFlag); credentialsContents != "" {
267+
if err = json.Unmarshal([]byte(credentialsContents), &credentials); err != nil {
268+
err = errInvalidJSONCredential{path: "TUNNEL_CRED_CONTENTS", err: err}
269+
}
270+
} else {
271+
credFinder := sc.credentialFinder(tunnelID)
272+
credentials, err = sc.readTunnelCredentials(credFinder)
273+
}
266274
// This line ensures backwards compatibility with credentials files generated before
267275
// TUN-3581. Those old credentials files don't have a TunnelID field, so we enrich the struct
268276
// with the ID, which we have already resolved from the user input.

cmd/cloudflared/tunnel/subcommand_context_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,51 @@ func Test_subcommandContext_findCredentials(t *testing.T) {
191191
TunnelName: name,
192192
},
193193
},
194+
{
195+
name: "TUNNEL_CRED_CONTENTS given contains old credentials contents",
196+
fields: fields{
197+
log: &log,
198+
fs: fs,
199+
c: func() *cli.Context {
200+
flagSet := flag.NewFlagSet("test0", flag.PanicOnError)
201+
flagSet.String(CredContentsFlag, "", "")
202+
c := cli.NewContext(cli.NewApp(), flagSet, nil)
203+
_ = c.Set(CredContentsFlag, fmt.Sprintf(`{"AccountTag":"%s","TunnelSecret":"%s"}`, accountTag, secretB64))
204+
return c
205+
}(),
206+
},
207+
args: args{
208+
tunnelID: tunnelID,
209+
},
210+
want: connection.Credentials{
211+
AccountTag: accountTag,
212+
TunnelID: tunnelID,
213+
TunnelSecret: secret,
214+
},
215+
},
216+
{
217+
name: "TUNNEL_CRED_CONTENTS given contains new credentials contents",
218+
fields: fields{
219+
log: &log,
220+
fs: fs,
221+
c: func() *cli.Context {
222+
flagSet := flag.NewFlagSet("test0", flag.PanicOnError)
223+
flagSet.String(CredContentsFlag, "", "")
224+
c := cli.NewContext(cli.NewApp(), flagSet, nil)
225+
_ = c.Set(CredContentsFlag, fmt.Sprintf(`{"AccountTag":"%s","TunnelSecret":"%s","TunnelID":"%s","TunnelName":"%s"}`, accountTag, secretB64, tunnelID, name))
226+
return c
227+
}(),
228+
},
229+
args: args{
230+
tunnelID: tunnelID,
231+
},
232+
want: connection.Credentials{
233+
AccountTag: accountTag,
234+
TunnelID: tunnelID,
235+
TunnelSecret: secret,
236+
TunnelName: name,
237+
},
238+
},
194239
}
195240
for _, tt := range tests {
196241
t.Run(tt.name, func(t *testing.T) {

cmd/cloudflared/tunnel/subcommands.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const (
3333
connsSortByOptions = "id, startedAt, numConnections, version"
3434
CredFileFlagAlias = "cred-file"
3535
CredFileFlag = "credentials-file"
36+
CredContentsFlag = "credentials-contents"
3637
overwriteDNSFlagName = "overwrite-dns"
3738

3839
LogFieldTunnelID = "tunnelID"
@@ -111,8 +112,13 @@ var (
111112
Usage: "Filepath at which to read/write the tunnel credentials",
112113
EnvVars: []string{"TUNNEL_CRED_FILE"},
113114
}
114-
credentialsFileFlag = altsrc.NewStringFlag(credentialsFileFlagCLIOnly)
115-
forceDeleteFlag = &cli.BoolFlag{
115+
credentialsFileFlag = altsrc.NewStringFlag(credentialsFileFlagCLIOnly)
116+
credentialsContentsFlag = altsrc.NewStringFlag(&cli.StringFlag{
117+
Name: CredContentsFlag,
118+
Usage: "Contents of the tunnel credentials JSON file to use. When provided along with credentials-file, this will take precedence.",
119+
EnvVars: []string{"TUNNEL_CRED_CONTENTS"},
120+
})
121+
forceDeleteFlag = &cli.BoolFlag{
116122
Name: "force",
117123
Aliases: []string{"f"},
118124
Usage: "Cleans up any stale connections before the tunnel is deleted. cloudflared will not " +
@@ -579,6 +585,7 @@ func buildRunCommand() *cli.Command {
579585
flags := []cli.Flag{
580586
forceFlag,
581587
credentialsFileFlag,
588+
credentialsContentsFlag,
582589
selectProtocolFlag,
583590
featuresFlag,
584591
}

0 commit comments

Comments
 (0)