@@ -51,7 +51,7 @@ type mockCloudFlareClient struct {
51
51
listZonesError error
52
52
listZonesContextError error
53
53
dnsRecordsError error
54
- customHostnames map [string ]map [ string ]cloudflare.CustomHostname
54
+ customHostnames map [string ][ ]cloudflare.CustomHostname
55
55
}
56
56
57
57
var ExampleDomain = []cloudflare.DNSRecord {
@@ -92,7 +92,7 @@ func NewMockCloudFlareClient() *mockCloudFlareClient {
92
92
"001" : {},
93
93
"002" : {},
94
94
},
95
- customHostnames : map [string ]map [ string ]cloudflare.CustomHostname {},
95
+ customHostnames : map [string ][ ]cloudflare.CustomHostname {},
96
96
}
97
97
}
98
98
@@ -261,55 +261,71 @@ func (m *mockCloudFlareClient) UserDetails(ctx context.Context) (cloudflare.User
261
261
262
262
func (m * mockCloudFlareClient ) CustomHostnames (ctx context.Context , zoneID string , page int , filter cloudflare.CustomHostname ) ([]cloudflare.CustomHostname , cloudflare.ResultInfo , error ) {
263
263
var err error = nil
264
+ perPage := 50 // cloudflare-go v0 API hardcoded
264
265
265
266
if strings .HasPrefix (zoneID , "newerror-" ) {
266
267
return nil , cloudflare.ResultInfo {}, errors .New ("failed to list custom hostnames" )
267
268
}
268
-
269
- if page != 1 || filter .Hostname != "" {
270
- err = errors .New ("pages and filters are not supported for custom hostnames mock test" )
269
+ if filter .Hostname != "" {
270
+ err = errors .New ("filters are not supported for custom hostnames mock test" )
271
+ return nil , cloudflare.ResultInfo {}, err
272
+ }
273
+ if page < 1 {
274
+ err = errors .New ("incorrect page value for custom hostnames list" )
275
+ return nil , cloudflare.ResultInfo {}, err
271
276
}
272
277
273
278
result := []cloudflare.CustomHostname {}
274
- if zone , ok := m .customHostnames [zoneID ]; ok {
275
- for _ , ch := range zone {
279
+ if chs , ok := m .customHostnames [zoneID ]; ok {
280
+ for idx := (page - 1 ) * perPage ; idx < min (len (chs ), page * perPage ); idx ++ {
281
+ ch := m.customHostnames [zoneID ][idx ]
276
282
if strings .HasPrefix (ch .Hostname , "newerror-list-" ) {
277
283
m .DeleteCustomHostname (ctx , zoneID , ch .ID )
278
284
return nil , cloudflare.ResultInfo {}, errors .New ("failed to list erroring custom hostname" )
279
285
}
280
286
result = append (result , ch )
281
287
}
288
+ return result ,
289
+ cloudflare.ResultInfo {
290
+ Page : page ,
291
+ PerPage : perPage ,
292
+ Count : len (result ),
293
+ Total : len (chs ),
294
+ TotalPages : len (chs )/ page + 1 ,
295
+ }, err
296
+ } else {
297
+ return result ,
298
+ cloudflare.ResultInfo {
299
+ Page : page ,
300
+ PerPage : perPage ,
301
+ Count : 0 ,
302
+ Total : 0 ,
303
+ TotalPages : 0 ,
304
+ }, err
282
305
}
283
-
284
- return result ,
285
- cloudflare.ResultInfo {
286
- Page : 1 ,
287
- PerPage : 100 ,
288
- Count : len (result ),
289
- Total : len (result ),
290
- TotalPages : 1 ,
291
- }, err
292
306
}
293
307
294
308
func (m * mockCloudFlareClient ) CreateCustomHostname (ctx context.Context , zoneID string , ch cloudflare.CustomHostname ) (* cloudflare.CustomHostnameResponse , error ) {
295
309
if ch .Hostname == "" || ch .CustomOriginServer == "" || ch .Hostname == "newerror-create.foo.fancybar.com" {
296
310
return nil , fmt .Errorf ("Invalid custom hostname or origin hostname" )
297
311
}
298
312
if _ , ok := m .customHostnames [zoneID ]; ! ok {
299
- m .customHostnames [zoneID ] = map [ string ]cloudflare.CustomHostname {}
313
+ m .customHostnames [zoneID ] = [ ]cloudflare.CustomHostname {}
300
314
}
301
315
var newCustomHostname cloudflare.CustomHostname = ch
302
316
newCustomHostname .ID = fmt .Sprintf ("ID-%s" , ch .Hostname )
303
- m.customHostnames [zoneID ][newCustomHostname. ID ] = newCustomHostname
317
+ m .customHostnames [zoneID ] = append ( m . customHostnames [ zoneID ], newCustomHostname )
304
318
return & cloudflare.CustomHostnameResponse {}, nil
305
319
}
306
320
307
321
func (m * mockCloudFlareClient ) DeleteCustomHostname (ctx context.Context , zoneID string , customHostnameID string ) error {
308
- if zone , ok := m .customHostnames [zoneID ]; ok {
309
- if _ , ok := zone [customHostnameID ]; ok {
310
- delete (zone , customHostnameID )
311
- }
322
+ idx := 0
323
+ if idx = getCustomHostnameIdxByID (m .customHostnames [zoneID ], customHostnameID ); idx < 0 {
324
+ return fmt .Errorf ("Invalid custom hostname ID to delete" )
312
325
}
326
+
327
+ m .customHostnames [zoneID ] = append (m .customHostnames [zoneID ][:idx ], m .customHostnames [zoneID ][idx + 1 :]... )
328
+
313
329
if customHostnameID == "ID-newerror-delete.foo.fancybar.com" {
314
330
return fmt .Errorf ("Invalid custom hostname to delete" )
315
331
}
@@ -379,6 +395,15 @@ func (m *mockCloudFlareClient) ZoneDetails(ctx context.Context, zoneID string) (
379
395
return cloudflare.Zone {}, errors .New ("Unknown zoneID: " + zoneID )
380
396
}
381
397
398
+ func getCustomHostnameIdxByID (chs []cloudflare.CustomHostname , customHostnameID string ) int {
399
+ for idx , ch := range chs {
400
+ if ch .ID == customHostnameID {
401
+ return idx
402
+ }
403
+ }
404
+ return - 1
405
+ }
406
+
382
407
func (p * CloudFlareProvider ) getCustomHostnameIDbyCustomHostnameAndOrigin (chs []cloudflare.CustomHostname , customHostname string , origin string ) (string , string ) {
383
408
for _ , zoneCh := range chs {
384
409
if zoneCh .Hostname == customHostname && zoneCh .CustomOriginServer == origin {
@@ -1720,7 +1745,7 @@ func TestCloudflareZoneRecordsFail(t *testing.T) {
1720
1745
"newerror-001" : "bar.com" ,
1721
1746
},
1722
1747
Records : map [string ]map [string ]cloudflare.DNSRecord {},
1723
- customHostnames : map [string ]map [ string ]cloudflare.CustomHostname {},
1748
+ customHostnames : map [string ][ ]cloudflare.CustomHostname {},
1724
1749
}
1725
1750
failingProvider := & CloudFlareProvider {
1726
1751
Client : client ,
@@ -2261,13 +2286,14 @@ func TestCloudflareCustomHostnameNotFoundOnRecordDeletion(t *testing.T) {
2261
2286
chID , _ := provider .getCustomHostnameOrigin (chs , "newerror-getCustomHostnameOrigin.foo.fancybar.com" )
2262
2287
if chID != "" {
2263
2288
t .Logf ("corrupting custom hostname %v" , chID )
2264
- oldCh := client.customHostnames [zoneID ][chID ]
2289
+ oldIdx := getCustomHostnameIdxByID (client .customHostnames [zoneID ], chID )
2290
+ oldCh := client.customHostnames [zoneID ][oldIdx ]
2265
2291
ch := cloudflare.CustomHostname {
2266
2292
Hostname : "corrupted-newerror-getCustomHostnameOrigin.foo.fancybar.com" ,
2267
2293
CustomOriginServer : oldCh .CustomOriginServer ,
2268
2294
SSL : oldCh .SSL ,
2269
2295
}
2270
- client.customHostnames [zoneID ][chID ] = ch
2296
+ client.customHostnames [zoneID ][oldIdx ] = ch
2271
2297
}
2272
2298
}
2273
2299
@@ -2278,3 +2304,62 @@ func TestCloudflareCustomHostnameNotFoundOnRecordDeletion(t *testing.T) {
2278
2304
}
2279
2305
assert .Contains (t , b .String (), "level=info msg=\" Custom hostname newerror-getCustomHostnameOrigin.foo.fancybar.com not found\" action=DELETE record=create.foo.bar.com" )
2280
2306
}
2307
+
2308
+ func TestCloudflareListCustomHostnamesWithPagionation (t * testing.T ) {
2309
+ client := NewMockCloudFlareClient ()
2310
+ provider := & CloudFlareProvider {
2311
+ Client : client ,
2312
+ CustomHostnamesConfig : CustomHostnamesConfig {Enabled : true },
2313
+ }
2314
+ ctx := context .Background ()
2315
+ domainFilter := endpoint .NewDomainFilter ([]string {"bar.com" })
2316
+
2317
+ const CustomHostnamesNumber = 342
2318
+ var generatedEndpoints []* endpoint.Endpoint
2319
+ for i := 0 ; i < CustomHostnamesNumber ; i ++ {
2320
+ ep := []* endpoint.Endpoint {
2321
+ {
2322
+ DNSName : fmt .Sprintf ("host-%d.foo.bar.com" , i ),
2323
+ Targets : endpoint.Targets {fmt .Sprintf ("cname-%d.foo.bar.com" , i )},
2324
+ RecordType : endpoint .RecordTypeCNAME ,
2325
+ RecordTTL : endpoint .TTL (defaultCloudFlareRecordTTL ),
2326
+ Labels : endpoint.Labels {},
2327
+ ProviderSpecific : endpoint.ProviderSpecific {
2328
+ {
2329
+ Name : "external-dns.alpha.kubernetes.io/cloudflare-custom-hostname" ,
2330
+ Value : fmt .Sprintf ("host-%d.foo.fancybar.com" , i ),
2331
+ },
2332
+ },
2333
+ },
2334
+ }
2335
+ generatedEndpoints = append (generatedEndpoints , ep ... )
2336
+ }
2337
+
2338
+ records , err := provider .Records (ctx )
2339
+ if err != nil {
2340
+ t .Errorf ("should not fail, %s" , err )
2341
+ }
2342
+
2343
+ endpoints , err := provider .AdjustEndpoints (generatedEndpoints )
2344
+
2345
+ assert .NoError (t , err )
2346
+ plan := & plan.Plan {
2347
+ Current : records ,
2348
+ Desired : endpoints ,
2349
+ DomainFilter : endpoint.MatchAllDomainFilters {& domainFilter },
2350
+ ManagedRecords : []string {endpoint .RecordTypeA , endpoint .RecordTypeCNAME },
2351
+ }
2352
+
2353
+ planned := plan .Calculate ()
2354
+
2355
+ err = provider .ApplyChanges (context .Background (), planned .Changes )
2356
+ if err != nil {
2357
+ t .Errorf ("should not fail - %s" , err )
2358
+ }
2359
+
2360
+ chs , chErr := provider .listCustomHostnamesWithPagination (ctx , "001" )
2361
+ if chErr != nil {
2362
+ t .Errorf ("should not fail - %s" , chErr )
2363
+ }
2364
+ assert .Equal (t , len (chs ), CustomHostnamesNumber )
2365
+ }
0 commit comments