Skip to content

Commit e4d9f80

Browse files
committed
feat: add upstream support in service transfer and diff logic
1 parent 0f2ec94 commit e4d9f80

File tree

4 files changed

+126
-15
lines changed

4 files changed

+126
-15
lines changed

internal/adc/client/kind_executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func (e *KindExecutor) convertADCTypesToKineTypes(adcTypes []string) []string {
187187
// ADC Service transfers to both Kine Service and Route
188188
kineTypesSet[string(kine.ResourceTypeService)] = true
189189
kineTypesSet[string(kine.ResourceTypeRoute)] = true
190+
kineTypesSet[string(kine.ResourceTypeUpstream)] = true
190191
case adctypes.TypeSSL:
191192
kineTypesSet[string(kine.ResourceTypeSSL)] = true
192193
case adctypes.TypeGlobalRule:

internal/adc/kine/diff.go

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Differ interface {
5757
type TransferredResources struct {
5858
Routes []*Route
5959
Services []*Service
60+
Upstreams []*Upstream
6061
SSLs []*SSL
6162
GlobalRules []*GlobalRule
6263
}
@@ -114,6 +115,15 @@ func (d *differ) Diff(newResources *TransferredResources, opts *DiffOptions) ([]
114115
events = append(events, serviceEvents...)
115116
}
116117

118+
// Diff upstreams
119+
if len(typesToDiff) == 0 || typesToDiff[string(ResourceTypeUpstream)] {
120+
upstreamEvents, err := d.diffUpstreams(newResources.Upstreams, listOpts)
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to diff upstreams: %w", err)
123+
}
124+
events = append(events, upstreamEvents...)
125+
}
126+
117127
// Diff SSLs
118128
if len(typesToDiff) == 0 || typesToDiff[string(ResourceTypeSSL)] {
119129
sslEvents, err := d.diffSSLs(newResources.SSLs, listOpts)
@@ -264,6 +274,69 @@ func (d *differ) diffServices(newServices []*Service, listOpts []ListOption) ([]
264274
return events, nil
265275
}
266276

277+
// diffUpstreams compares new upstreams with cached upstreams
278+
func (d *differ) diffUpstreams(newUpstreams []*Upstream, listOpts []ListOption) ([]Event, error) {
279+
// Get cached upstreams
280+
cachedUpstreams, err := d.cache.ListUpstreams(listOpts...)
281+
if err != nil {
282+
return nil, fmt.Errorf("failed to list cached upstreams: %w", err)
283+
}
284+
285+
// Build maps for comparison
286+
newMap := make(map[string]*Upstream)
287+
for _, upstream := range newUpstreams {
288+
newMap[upstream.ID] = upstream
289+
}
290+
291+
cachedMap := make(map[string]*Upstream)
292+
for _, upstream := range cachedUpstreams {
293+
cachedMap[upstream.ID] = upstream
294+
}
295+
296+
var events []Event
297+
298+
// Find CREATE and UPDATE events
299+
for id, newUpstream := range newMap {
300+
if cachedUpstream, exists := cachedMap[id]; exists {
301+
// Check if update is needed
302+
if !areUpstreamsEqual(cachedUpstream, newUpstream) {
303+
events = append(events, Event{
304+
Type: EventTypeUpdate,
305+
ResourceType: ResourceTypeUpstream,
306+
ResourceID: id,
307+
ResourceName: newUpstream.Name,
308+
OldValue: cachedUpstream,
309+
NewValue: newUpstream,
310+
})
311+
}
312+
} else {
313+
// Create new upstream
314+
events = append(events, Event{
315+
Type: EventTypeCreate,
316+
ResourceType: ResourceTypeUpstream,
317+
ResourceID: id,
318+
ResourceName: newUpstream.Name,
319+
NewValue: newUpstream,
320+
})
321+
}
322+
}
323+
324+
// Find DELETE events
325+
for id, cachedUpstream := range cachedMap {
326+
if _, exists := newMap[id]; !exists {
327+
events = append(events, Event{
328+
Type: EventTypeDelete,
329+
ResourceType: ResourceTypeUpstream,
330+
ResourceID: id,
331+
ResourceName: cachedUpstream.Name,
332+
OldValue: cachedUpstream,
333+
})
334+
}
335+
}
336+
337+
return events, nil
338+
}
339+
267340
// diffSSLs compares new SSLs with cached SSLs
268341
func (d *differ) diffSSLs(newSSLs []*SSL, listOpts []ListOption) ([]Event, error) {
269342
// Get cached SSLs
@@ -402,6 +475,11 @@ func areServicesEqual(a, b *Service) bool {
402475
return cmp.Equal(a, b)
403476
}
404477

478+
// areUpstreamsEqual compares two upstreams for equality using go-cmp
479+
func areUpstreamsEqual(a, b *Upstream) bool {
480+
return cmp.Equal(a, b)
481+
}
482+
405483
// areSSLsEqual compares two SSLs for equality using go-cmp
406484
func areSSLsEqual(a, b *SSL) bool {
407485
return cmp.Equal(a, b)
@@ -475,14 +553,16 @@ func TransferResources(resources *adc.Resources) (*TransferredResources, error)
475553

476554
// Transfer services (which includes routes and upstream)
477555
for _, adcService := range resources.Services {
478-
kineService, kineRoutes, err := TransferService(adcService)
556+
kineService, kineRoutes, kineUpstreams, err := TransferService(adcService)
479557
if err != nil {
480558
return nil, fmt.Errorf("failed to transfer service %s: %w", adcService.Name, err)
481559
}
482560
if kineService != nil {
483561
result.Services = append(result.Services, kineService)
484562
}
485563
result.Routes = append(result.Routes, kineRoutes...)
564+
565+
result.Upstreams = append(result.Upstreams, kineUpstreams...)
486566
}
487567

488568
// Transfer SSLs

internal/adc/kine/transfer.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import (
1010
)
1111

1212
// TransferService converts an ADC Service to Kine Service and Routes
13-
func TransferService(adcSvc *adc.Service) (*Service, []*Route, error) {
13+
func TransferService(adcSvc *adc.Service) (*Service, []*Route, []*Upstream, error) {
1414
if adcSvc == nil {
15-
return nil, nil, fmt.Errorf("adc service is nil")
15+
return nil, nil, nil, fmt.Errorf("adc service is nil")
1616
}
1717

1818
// Ignore Upstreams, only use Upstream
1919
if adcSvc.Upstream == nil {
20-
return nil, nil, fmt.Errorf("adc service upstream is nil")
20+
return nil, nil, nil, fmt.Errorf("adc service upstream is nil")
2121
}
2222

2323
// Convert ADC Service to Kine Service
@@ -29,7 +29,7 @@ func TransferService(adcSvc *adc.Service) (*Service, []*Route, error) {
2929
Labels: copyLabels(adcSvc.Labels),
3030
},
3131
Plugins: convertPlugins(adcSvc.Plugins),
32-
Upstream: convertUpstream(adcSvc.Upstream),
32+
Upstream: convertUpstream(adcSvc.Upstream, adcSvc),
3333
Hosts: copyStringSlice(adcSvc.Hosts),
3434
}
3535

@@ -38,12 +38,21 @@ func TransferService(adcSvc *adc.Service) (*Service, []*Route, error) {
3838
for _, adcRoute := range adcSvc.Routes {
3939
kineRoute, err := convertRoute(adcRoute, adcSvc)
4040
if err != nil {
41-
return nil, nil, fmt.Errorf("failed to convert route: %w", err)
41+
return nil, nil, nil, fmt.Errorf("failed to convert route: %w", err)
4242
}
4343
kineRoutes = append(kineRoutes, kineRoute)
4444
}
4545

46-
return kineSvc, kineRoutes, nil
46+
// Convert ADC Upstream to Kine Upstream
47+
kineUpstreams := make([]*Upstream, 0, len(adcSvc.Upstreams))
48+
if adcSvc.Upstreams != nil {
49+
for _, adcUpstream := range adcSvc.Upstreams {
50+
kineUpstream := convertUpstream(adcUpstream, adcSvc)
51+
kineUpstreams = append(kineUpstreams, kineUpstream)
52+
}
53+
}
54+
55+
return kineSvc, kineRoutes, kineUpstreams, nil
4756
}
4857

4958
// generateServiceID generates service ID from name using SHA1
@@ -103,7 +112,7 @@ func convertRoute(adcRoute *adc.Route, adcSvc *adc.Service) (*Route, error) {
103112
}
104113

105114
// convertUpstream converts ADC Upstream to Kine Upstream
106-
func convertUpstream(adcUpstream *adc.Upstream) *Upstream {
115+
func convertUpstream(adcUpstream *adc.Upstream, adcSvc *adc.Service) *Upstream {
107116
if adcUpstream == nil {
108117
return nil
109118
}
@@ -119,7 +128,7 @@ func convertUpstream(adcUpstream *adc.Upstream) *Upstream {
119128
ID: upstreamID,
120129
Name: adcUpstream.Name,
121130
Desc: adcUpstream.Desc,
122-
Labels: copyLabels(adcUpstream.Labels),
131+
Labels: copyLabels(adcSvc.Labels),
123132
},
124133
Nodes: convertNodes(adcUpstream.Nodes),
125134
Type: convertUpstreamType(adcUpstream.Type),

internal/adc/kine/transfer_test.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func TestTransferService(t *testing.T) {
6767
}
6868

6969
// Test TransferService
70-
kineSvc, kineRoutes, err := TransferService(adcSvc)
70+
kineSvc, kineRoutes, _, err := TransferService(adcSvc)
7171
if err != nil {
7272
t.Fatalf("TransferService failed: %v", err)
7373
}
@@ -175,7 +175,7 @@ func TestTransferServiceWithCustomID(t *testing.T) {
175175
},
176176
}
177177

178-
kineSvc, kineRoutes, err := TransferService(adcSvc)
178+
kineSvc, kineRoutes, _, err := TransferService(adcSvc)
179179
if err != nil {
180180
t.Fatalf("TransferService failed: %v", err)
181181
}
@@ -199,7 +199,7 @@ func TestTransferServiceNilUpstream(t *testing.T) {
199199
Upstream: nil,
200200
}
201201

202-
_, _, err := TransferService(adcSvc)
202+
_, _, _, err := TransferService(adcSvc)
203203
if err == nil {
204204
t.Error("Expected error for nil upstream")
205205
}
@@ -357,7 +357,14 @@ func TestConvertUpstreamWithoutID(t *testing.T) {
357357
Scheme: "http",
358358
}
359359

360-
result := convertUpstream(adcUpstream)
360+
// Create a service to pass to convertUpstream
361+
adcSvc := &adc.Service{
362+
Metadata: adc.Metadata{
363+
Name: "test-service",
364+
},
365+
}
366+
367+
result := convertUpstream(adcUpstream, adcSvc)
361368

362369
if result == nil {
363370
t.Fatal("Result should not be nil")
@@ -387,7 +394,14 @@ func TestConvertUpstreamWithID(t *testing.T) {
387394
Scheme: "http",
388395
}
389396

390-
result := convertUpstream(adcUpstream)
397+
// Create a service to pass to convertUpstream
398+
adcSvc := &adc.Service{
399+
Metadata: adc.Metadata{
400+
Name: "test-service",
401+
},
402+
}
403+
404+
result := convertUpstream(adcUpstream, adcSvc)
391405

392406
if result == nil {
393407
t.Fatal("Result should not be nil")
@@ -437,7 +451,14 @@ func TestConvertUpstreamWithHealthCheck(t *testing.T) {
437451
},
438452
}
439453

440-
result := convertUpstream(adcUpstream)
454+
// Create a service to pass to convertUpstream
455+
adcSvc := &adc.Service{
456+
Metadata: adc.Metadata{
457+
Name: "test-service",
458+
},
459+
}
460+
461+
result := convertUpstream(adcUpstream, adcSvc)
441462

442463
if result == nil {
443464
t.Fatal("Result should not be nil")

0 commit comments

Comments
 (0)