Skip to content

Commit 958650b

Browse files
committed
TUN-5262: Improvements to max-fetch-size that allow to deal with large number of tunnels in account
* `max-fetch-size` can now be set up in the config YAML * we no longer pass that to filter commands that filter by name * flag changed to signed int since altsrc does not support UInt flags * we now look up each non UUID (to convert it to a UUID) when needed, separately
1 parent eb51ff0 commit 958650b

File tree

4 files changed

+30
-121
lines changed

4 files changed

+30
-121
lines changed

cmd/cloudflared/tunnel/cmd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,12 +646,12 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
646646
Value: "https://api.trycloudflare.com",
647647
Hidden: true,
648648
}),
649-
&cli.UintFlag{
649+
altsrc.NewIntFlag(&cli.IntFlag{
650650
Name: "max-fetch-size",
651651
Usage: `The maximum number of results that cloudflared can fetch from Cloudflare API for any listing operations needed`,
652652
EnvVars: []string{"TUNNEL_MAX_FETCH_SIZE"},
653653
Hidden: true,
654-
},
654+
}),
655655
selectProtocolFlag,
656656
overwriteDNSFlag,
657657
}...)

cmd/cloudflared/tunnel/subcommand_context.go

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,6 @@ func (sc *subcommandContext) tunnelActive(name string) (*tunnelstore.Tunnel, boo
336336
filter := tunnelstore.NewFilter()
337337
filter.NoDeleted()
338338
filter.ByName(name)
339-
if maxFetch := sc.c.Uint("max-fetch-size"); maxFetch > 0 {
340-
filter.MaxFetchSize(maxFetch)
341-
}
342-
343339
tunnels, err := sc.list(filter)
344340
if err != nil {
345341
return nil, false, err
@@ -377,56 +373,42 @@ func (sc *subcommandContext) findID(input string) (uuid.UUID, error) {
377373
}
378374

379375
// findIDs is just like mapping `findID` over a slice, but it only uses
380-
// one Tunnelstore API call.
376+
// one Tunnelstore API call per non-UUID input provided.
381377
func (sc *subcommandContext) findIDs(inputs []string) ([]uuid.UUID, error) {
378+
uuids, names := splitUuids(inputs)
382379

383-
// Shortcut without Tunnelstore call if we find that all inputs are already UUIDs.
384-
uuids, err := convertNamesToUuids(inputs, make(map[string]uuid.UUID))
385-
if err == nil {
386-
return uuids, nil
387-
}
380+
for _, name := range names {
381+
filter := tunnelstore.NewFilter()
382+
filter.NoDeleted()
383+
filter.ByName(name)
388384

389-
// First, look up all tunnels the user has
390-
filter := tunnelstore.NewFilter()
391-
filter.NoDeleted()
392-
if maxFetch := sc.c.Uint("max-fetch-size"); maxFetch > 0 {
393-
filter.MaxFetchSize(maxFetch)
394-
}
385+
tunnels, err := sc.list(filter)
386+
if err != nil {
387+
return nil, err
388+
}
395389

396-
tunnels, err := sc.list(filter)
397-
if err != nil {
398-
return nil, err
399-
}
400-
// Do the pure list-processing in its own function, so that it can be
401-
// unit tested easily.
402-
return findIDs(tunnels, inputs)
403-
}
390+
if len(tunnels) != 1 {
391+
return nil, fmt.Errorf("there should only be 1 non-deleted Tunnel named %s", name)
392+
}
404393

405-
func findIDs(tunnels []*tunnelstore.Tunnel, inputs []string) ([]uuid.UUID, error) {
406-
// Put them into a dictionary for faster lookups
407-
nameToID := make(map[string]uuid.UUID, len(tunnels))
408-
for _, tunnel := range tunnels {
409-
nameToID[tunnel.Name] = tunnel.ID
394+
uuids = append(uuids, tunnels[0].ID)
410395
}
411396

412-
return convertNamesToUuids(inputs, nameToID)
397+
return uuids, nil
413398
}
414399

415-
func convertNamesToUuids(inputs []string, nameToID map[string]uuid.UUID) ([]uuid.UUID, error) {
416-
tunnelIDs := make([]uuid.UUID, len(inputs))
417-
var badInputs []string
418-
for i, input := range inputs {
419-
if id, err := uuid.Parse(input); err == nil {
420-
tunnelIDs[i] = id
421-
} else if id, ok := nameToID[input]; ok {
422-
tunnelIDs[i] = id
400+
func splitUuids(inputs []string) ([]uuid.UUID, []string) {
401+
uuids := make([]uuid.UUID, 0)
402+
names := make([]string, 0)
403+
404+
for _, input := range inputs {
405+
id, err := uuid.Parse(input)
406+
if err != nil {
407+
names = append(names, input)
423408
} else {
424-
badInputs = append(badInputs, input)
409+
uuids = append(uuids, id)
425410
}
426411
}
427-
if len(badInputs) > 0 {
428-
msg := "Please specify either the ID or name of a tunnel. The following inputs were neither: %s"
429-
return nil, fmt.Errorf(msg, strings.Join(badInputs, ", "))
430-
}
431-
return tunnelIDs, nil
412+
413+
return uuids, names
432414
}

cmd/cloudflared/tunnel/subcommand_context_test.go

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,79 +17,6 @@ import (
1717
"github.com/cloudflare/cloudflared/tunnelstore"
1818
)
1919

20-
func Test_findIDs(t *testing.T) {
21-
type args struct {
22-
tunnels []*tunnelstore.Tunnel
23-
inputs []string
24-
}
25-
tests := []struct {
26-
name string
27-
args args
28-
want []uuid.UUID
29-
wantErr bool
30-
}{
31-
{
32-
name: "input not found",
33-
args: args{
34-
inputs: []string{"asdf"},
35-
},
36-
wantErr: true,
37-
},
38-
{
39-
name: "only UUID",
40-
args: args{
41-
inputs: []string{"a8398a0b-876d-48ed-b609-3fcfd67a4950"},
42-
},
43-
want: []uuid.UUID{uuid.MustParse("a8398a0b-876d-48ed-b609-3fcfd67a4950")},
44-
},
45-
{
46-
name: "only name",
47-
args: args{
48-
tunnels: []*tunnelstore.Tunnel{
49-
{
50-
ID: uuid.MustParse("a8398a0b-876d-48ed-b609-3fcfd67a4950"),
51-
Name: "tunnel1",
52-
},
53-
},
54-
inputs: []string{"tunnel1"},
55-
},
56-
want: []uuid.UUID{uuid.MustParse("a8398a0b-876d-48ed-b609-3fcfd67a4950")},
57-
},
58-
{
59-
name: "both UUID and name",
60-
args: args{
61-
tunnels: []*tunnelstore.Tunnel{
62-
{
63-
ID: uuid.MustParse("a8398a0b-876d-48ed-b609-3fcfd67a4950"),
64-
Name: "tunnel1",
65-
},
66-
{
67-
ID: uuid.MustParse("bf028b68-744f-466e-97f8-c46161d80aa5"),
68-
Name: "tunnel2",
69-
},
70-
},
71-
inputs: []string{"tunnel1", "bf028b68-744f-466e-97f8-c46161d80aa5"},
72-
},
73-
want: []uuid.UUID{
74-
uuid.MustParse("a8398a0b-876d-48ed-b609-3fcfd67a4950"),
75-
uuid.MustParse("bf028b68-744f-466e-97f8-c46161d80aa5"),
76-
},
77-
},
78-
}
79-
for _, tt := range tests {
80-
t.Run(tt.name, func(t *testing.T) {
81-
got, err := findIDs(tt.args.tunnels, tt.args.inputs)
82-
if (err != nil) != tt.wantErr {
83-
t.Errorf("findIDs() error = %v, wantErr %v", err, tt.wantErr)
84-
return
85-
}
86-
if !reflect.DeepEqual(got, tt.want) {
87-
t.Errorf("findIDs() = %v, want %v", got, tt.want)
88-
}
89-
})
90-
}
91-
}
92-
9320
type mockFileSystem struct {
9421
rf func(string) ([]byte, error)
9522
vfp func(string) bool

cmd/cloudflared/tunnel/subcommands.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ func listCommand(c *cli.Context) error {
277277
}
278278
filter.ByTunnelID(tunnelID)
279279
}
280-
if maxFetch := c.Uint("max-fetch-size"); maxFetch > 0 {
281-
filter.MaxFetchSize(maxFetch)
280+
if maxFetch := c.Int("max-fetch-size"); maxFetch > 0 {
281+
filter.MaxFetchSize(uint(maxFetch))
282282
}
283283

284284
tunnels, err := sc.list(filter)

0 commit comments

Comments
 (0)