@@ -44,7 +44,7 @@ type MarshalFunc[T any] func(T, ...services.MarshalOption) ([]byte, error)
44
44
type UnmarshalFunc [T any ] func ([]byte , ... services.MarshalOption ) (T , error )
45
45
46
46
// ServiceConfig is the configuration for the service configuration.
47
- type ServiceConfig [T Resource ] struct {
47
+ type ServiceConfig [T any ] struct {
48
48
// Backend used to persist the resource.
49
49
Backend backend.Backend
50
50
// ResourceKind is the friendly name of the resource.
@@ -64,9 +64,10 @@ type ServiceConfig[T Resource] struct {
64
64
// If set to 0, the default interval of 250ms will be used.
65
65
// WARNING: If set to a negative value, the RunWhileLocked function will retry immediately.
66
66
RunWhileLockedRetryInterval time.Duration
67
- // KeyFunc optionally allows resource to have a custom key. If not provided the
68
- // name of the resource will be used.
69
- KeyFunc func (T ) string
67
+ // NameKeyFunc optionally allows resources to have a custom key suffix, by
68
+ // transforming the name of the resource or the input given to methods that
69
+ // take a resource name. If unset, the name is used without changes.
70
+ NameKeyFunc func (name string ) string
70
71
}
71
72
72
73
func (c * ServiceConfig [T ]) CheckAndSetDefaults () error {
@@ -95,10 +96,6 @@ func (c *ServiceConfig[T]) CheckAndSetDefaults() error {
95
96
c .ValidateFunc = func (t T ) error { return nil }
96
97
}
97
98
98
- if c .KeyFunc == nil {
99
- c .KeyFunc = func (t T ) string { return t .GetName () }
100
- }
101
-
102
99
return nil
103
100
}
104
101
@@ -112,7 +109,7 @@ type Service[T Resource] struct {
112
109
unmarshalFunc UnmarshalFunc [T ]
113
110
validateFunc func (T ) error
114
111
runWhileLockedRetryInterval time.Duration
115
- keyFunc func (T ) string
112
+ nameKeyFunc func (name string ) string
116
113
}
117
114
118
115
// NewService will return a new generic service with the given config. This will
@@ -131,7 +128,7 @@ func NewService[T Resource](cfg *ServiceConfig[T]) (*Service[T], error) {
131
128
unmarshalFunc : cfg .UnmarshalFunc ,
132
129
validateFunc : cfg .ValidateFunc ,
133
130
runWhileLockedRetryInterval : cfg .RunWhileLockedRetryInterval ,
134
- keyFunc : cfg .KeyFunc ,
131
+ nameKeyFunc : cfg .NameKeyFunc ,
135
132
}, nil
136
133
}
137
134
@@ -140,18 +137,16 @@ func (s *Service[T]) WithPrefix(parts ...string) *Service[T] {
140
137
if len (parts ) == 0 {
141
138
return s
142
139
}
140
+ s2 := * s
141
+ s2 .backendPrefix = s2 .backendPrefix .AppendKey (backend .NewKey (parts ... ))
142
+ return & s2
143
+ }
143
144
144
- return & Service [T ]{
145
- backend : s .backend ,
146
- resourceKind : s .resourceKind ,
147
- pageLimit : s .pageLimit ,
148
- backendPrefix : s .backendPrefix .AppendKey (backend .NewKey (parts ... )),
149
- marshalFunc : s .marshalFunc ,
150
- unmarshalFunc : s .unmarshalFunc ,
151
- validateFunc : s .validateFunc ,
152
- runWhileLockedRetryInterval : s .runWhileLockedRetryInterval ,
153
- keyFunc : s .keyFunc ,
145
+ func (s * Service [T ]) nameKey (name string ) string {
146
+ if s .nameKeyFunc != nil {
147
+ return s .nameKeyFunc (name )
154
148
}
149
+ return name
155
150
}
156
151
157
152
// CountResources will return a count of all resources in the prefix range.
@@ -204,6 +199,7 @@ func (s *Service[T]) ListResourcesReturnNextResource(ctx context.Context, pageSi
204
199
resources , next , _ , err := s .listResourcesReturnNextResourceWithKey (ctx , pageSize , pageToken )
205
200
return resources , next , trace .Wrap (err )
206
201
}
202
+
207
203
func (s * Service [T ]) listResourcesReturnNextResourceWithKey (ctx context.Context , pageSize int , pageToken string ) ([]T , * T , string , error ) {
208
204
rangeStart := s .backendPrefix .AppendKey (backend .KeyFromString (pageToken ))
209
205
rangeEnd := backend .RangeEnd (s .backendPrefix .ExactKey ())
@@ -291,12 +287,11 @@ func (s *Service[T]) ListResourcesWithFilter(ctx context.Context, pageSize int,
291
287
}
292
288
293
289
return resources , nextKey , nil
294
-
295
290
}
296
291
297
292
// GetResource returns the specified resource.
298
293
func (s * Service [T ]) GetResource (ctx context.Context , name string ) (resource T , err error ) {
299
- item , err := s .backend .Get (ctx , s .MakeKey (backend .NewKey (name )))
294
+ item , err := s .backend .Get (ctx , s .MakeKey (backend .NewKey (s . nameKey ( name ) )))
300
295
if err != nil {
301
296
if trace .IsNotFound (err ) {
302
297
return resource , trace .NotFound ("%s %q doesn't exist" , s .resourceKind , name )
@@ -315,7 +310,7 @@ func (s *Service[T]) CreateResource(ctx context.Context, resource T) (T, error)
315
310
return t , trace .Wrap (err )
316
311
}
317
312
318
- item , err := s .MakeBackendItem (resource , s . keyFunc ( resource ) )
313
+ item , err := s .MakeBackendItem (resource )
319
314
if err != nil {
320
315
return t , trace .Wrap (err )
321
316
}
@@ -340,7 +335,7 @@ func (s *Service[T]) UpdateResource(ctx context.Context, resource T) (T, error)
340
335
return t , trace .Wrap (err )
341
336
}
342
337
343
- item , err := s .MakeBackendItem (resource , s . keyFunc ( resource ) )
338
+ item , err := s .MakeBackendItem (resource )
344
339
if err != nil {
345
340
return t , trace .Wrap (err )
346
341
}
@@ -365,7 +360,7 @@ func (s *Service[T]) ConditionalUpdateResource(ctx context.Context, resource T)
365
360
return t , trace .Wrap (err )
366
361
}
367
362
368
- item , err := s .MakeBackendItem (resource , s . keyFunc ( resource ) )
363
+ item , err := s .MakeBackendItem (resource )
369
364
if err != nil {
370
365
return t , trace .Wrap (err )
371
366
}
@@ -390,7 +385,7 @@ func (s *Service[T]) UpsertResource(ctx context.Context, resource T) (T, error)
390
385
return t , trace .Wrap (err )
391
386
}
392
387
393
- item , err := s .MakeBackendItem (resource , s . keyFunc ( resource ) )
388
+ item , err := s .MakeBackendItem (resource )
394
389
if err != nil {
395
390
return t , trace .Wrap (err )
396
391
}
@@ -406,7 +401,7 @@ func (s *Service[T]) UpsertResource(ctx context.Context, resource T) (T, error)
406
401
407
402
// DeleteResource removes the specified resource.
408
403
func (s * Service [T ]) DeleteResource (ctx context.Context , name string ) error {
409
- err := s .backend .Delete (ctx , s .MakeKey (backend .NewKey (name )))
404
+ err := s .backend .Delete (ctx , s .MakeKey (backend .NewKey (s . nameKey ( name ) )))
410
405
if err != nil {
411
406
if trace .IsNotFound (err ) {
412
407
return trace .NotFound ("%s %q doesn't exist" , s .resourceKind , name )
@@ -425,7 +420,7 @@ func (s *Service[T]) DeleteAllResources(ctx context.Context) error {
425
420
// UpdateAndSwapResource will get the resource from the backend, modify it, and swap the new value into the backend.
426
421
func (s * Service [T ]) UpdateAndSwapResource (ctx context.Context , name string , modify func (T ) error ) (T , error ) {
427
422
var t T
428
- existingItem , err := s .backend .Get (ctx , s .MakeKey (backend .NewKey (name )))
423
+ existingItem , err := s .backend .Get (ctx , s .MakeKey (backend .NewKey (s . nameKey ( name ) )))
429
424
if err != nil {
430
425
if trace .IsNotFound (err ) {
431
426
return t , trace .NotFound ("%s %q doesn't exist" , s .resourceKind , name )
@@ -447,7 +442,7 @@ func (s *Service[T]) UpdateAndSwapResource(ctx context.Context, name string, mod
447
442
return t , trace .Wrap (err )
448
443
}
449
444
450
- replacementItem , err := s .MakeBackendItem (resource , name )
445
+ replacementItem , err := s .MakeBackendItem (resource )
451
446
if err != nil {
452
447
return t , trace .Wrap (err )
453
448
}
@@ -462,7 +457,8 @@ func (s *Service[T]) UpdateAndSwapResource(ctx context.Context, name string, mod
462
457
}
463
458
464
459
// MakeBackendItem will check and make the backend item.
465
- func (s * Service [T ]) MakeBackendItem (resource T , name string ) (backend.Item , error ) {
460
+ func (s * Service [T ]) MakeBackendItem (resource T , _ ... any ) (backend.Item , error ) {
461
+ // TODO(espadolini): clean up unused variadic after teleport.e is updated
466
462
if err := services .CheckAndSetDefaults (resource ); err != nil {
467
463
return backend.Item {}, trace .Wrap (err )
468
464
}
@@ -477,7 +473,7 @@ func (s *Service[T]) MakeBackendItem(resource T, name string) (backend.Item, err
477
473
return backend.Item {}, trace .Wrap (err )
478
474
}
479
475
item := backend.Item {
480
- Key : s .MakeKey (backend .NewKey (name )),
476
+ Key : s .MakeKey (backend .NewKey (s . nameKey ( resource . GetName ()) )),
481
477
Value : value ,
482
478
Revision : rev ,
483
479
}
0 commit comments