• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / external-dns / 14954656447

11 May 2025 10:00AM UTC coverage: 72.755% (+0.5%) from 72.283%
14954656447

Pull #5353

github

ivankatliarchuk
chore(docs): update aws permissions

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
Pull Request #5353: WIP chore(docs): update aws role requirements with conditions

14842 of 20400 relevant lines covered (72.75%)

692.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.24
/source/traefik_proxy.go
1
/*
2
Copyright 2022 The Kubernetes Authors.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package source
18

19
import (
20
        "context"
21
        "errors"
22
        "fmt"
23
        "regexp"
24
        "sort"
25
        "strings"
26

27
        log "github.com/sirupsen/logrus"
28
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
        "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
30
        "k8s.io/apimachinery/pkg/labels"
31
        "k8s.io/apimachinery/pkg/runtime"
32
        "k8s.io/apimachinery/pkg/runtime/schema"
33
        "k8s.io/client-go/dynamic"
34
        "k8s.io/client-go/dynamic/dynamicinformer"
35
        "k8s.io/client-go/informers"
36
        "k8s.io/client-go/kubernetes"
37
        "k8s.io/client-go/kubernetes/scheme"
38
        "k8s.io/client-go/tools/cache"
39

40
        "sigs.k8s.io/external-dns/endpoint"
41
)
42

43
var (
44
        ingressrouteGVR = schema.GroupVersionResource{
45
                Group:    "traefik.io",
46
                Version:  "v1alpha1",
47
                Resource: "ingressroutes",
48
        }
49
        ingressrouteTCPGVR = schema.GroupVersionResource{
50
                Group:    "traefik.io",
51
                Version:  "v1alpha1",
52
                Resource: "ingressroutetcps",
53
        }
54
        ingressrouteUDPGVR = schema.GroupVersionResource{
55
                Group:    "traefik.io",
56
                Version:  "v1alpha1",
57
                Resource: "ingressrouteudps",
58
        }
59
        oldIngressrouteGVR = schema.GroupVersionResource{
60
                Group:    "traefik.containo.us",
61
                Version:  "v1alpha1",
62
                Resource: "ingressroutes",
63
        }
64
        oldIngressrouteTCPGVR = schema.GroupVersionResource{
65
                Group:    "traefik.containo.us",
66
                Version:  "v1alpha1",
67
                Resource: "ingressroutetcps",
68
        }
69
        oldIngressrouteUDPGVR = schema.GroupVersionResource{
70
                Group:    "traefik.containo.us",
71
                Version:  "v1alpha1",
72
                Resource: "ingressrouteudps",
73
        }
74
)
75

76
var (
77
        traefikHostExtractor  = regexp.MustCompile(`(?:HostSNI|HostHeader|Host)\s*\(\s*(\x60.*?\x60)\s*\)`)
78
        traefikValueProcessor = regexp.MustCompile(`\x60([^,\x60]+)\x60`)
79
)
80

81
type traefikSource struct {
82
        annotationFilter           string
83
        ignoreHostnameAnnotation   bool
84
        dynamicKubeClient          dynamic.Interface
85
        ingressRouteInformer       informers.GenericInformer
86
        ingressRouteTcpInformer    informers.GenericInformer
87
        ingressRouteUdpInformer    informers.GenericInformer
88
        oldIngressRouteInformer    informers.GenericInformer
89
        oldIngressRouteTcpInformer informers.GenericInformer
90
        oldIngressRouteUdpInformer informers.GenericInformer
91
        kubeClient                 kubernetes.Interface
92
        namespace                  string
93
        unstructuredConverter      *unstructuredConverter
94
}
95

96
func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface, kubeClient kubernetes.Interface, namespace string, annotationFilter string, ignoreHostnameAnnotation bool, disableLegacy bool, disableNew bool) (Source, error) {
37✔
97
        // Use shared informer to listen for add/update/delete of Host in the specified namespace.
37✔
98
        // Set resync period to 0, to prevent processing when nothing has changed.
37✔
99
        informerFactory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(dynamicKubeClient, 0, namespace, nil)
37✔
100
        var ingressRouteInformer, ingressRouteTcpInformer, ingressRouteUdpInformer informers.GenericInformer
37✔
101
        var oldIngressRouteInformer, oldIngressRouteTcpInformer, oldIngressRouteUdpInformer informers.GenericInformer
37✔
102

37✔
103
        // Add default resource event handlers to properly initialize informers.
37✔
104
        if !disableNew {
73✔
105
                ingressRouteInformer = informerFactory.ForResource(ingressrouteGVR)
36✔
106
                ingressRouteTcpInformer = informerFactory.ForResource(ingressrouteTCPGVR)
36✔
107
                ingressRouteUdpInformer = informerFactory.ForResource(ingressrouteUDPGVR)
36✔
108
                ingressRouteInformer.Informer().AddEventHandler(
36✔
109
                        cache.ResourceEventHandlerFuncs{
36✔
110
                                AddFunc: func(obj interface{}) {},
44✔
111
                        },
112
                )
113
                ingressRouteTcpInformer.Informer().AddEventHandler(
36✔
114
                        cache.ResourceEventHandlerFuncs{
36✔
115
                                AddFunc: func(obj interface{}) {},
42✔
116
                        },
117
                )
118
                ingressRouteUdpInformer.Informer().AddEventHandler(
36✔
119
                        cache.ResourceEventHandlerFuncs{
36✔
120
                                AddFunc: func(obj interface{}) {},
39✔
121
                        },
122
                )
123
        }
124
        if !disableLegacy {
73✔
125
                oldIngressRouteInformer = informerFactory.ForResource(oldIngressrouteGVR)
36✔
126
                oldIngressRouteTcpInformer = informerFactory.ForResource(oldIngressrouteTCPGVR)
36✔
127
                oldIngressRouteUdpInformer = informerFactory.ForResource(oldIngressrouteUDPGVR)
36✔
128
                oldIngressRouteInformer.Informer().AddEventHandler(
36✔
129
                        cache.ResourceEventHandlerFuncs{
36✔
130
                                AddFunc: func(obj interface{}) {},
44✔
131
                        },
132
                )
133
                oldIngressRouteTcpInformer.Informer().AddEventHandler(
36✔
134
                        cache.ResourceEventHandlerFuncs{
36✔
135
                                AddFunc: func(obj interface{}) {},
42✔
136
                        },
137
                )
138
                oldIngressRouteUdpInformer.Informer().AddEventHandler(
36✔
139
                        cache.ResourceEventHandlerFuncs{
36✔
140
                                AddFunc: func(obj interface{}) {},
39✔
141
                        },
142
                )
143
        }
144

145
        informerFactory.Start((ctx.Done()))
37✔
146

37✔
147
        // wait for the local cache to be populated.
37✔
148
        if err := waitForDynamicCacheSync(context.Background(), informerFactory); err != nil {
37✔
149
                return nil, err
×
150
        }
×
151

152
        uc, err := newTraefikUnstructuredConverter()
37✔
153
        if err != nil {
37✔
154
                return nil, fmt.Errorf("failed to setup Unstructured Converter: %w", err)
×
155
        }
×
156

157
        return &traefikSource{
37✔
158
                annotationFilter:           annotationFilter,
37✔
159
                ignoreHostnameAnnotation:   ignoreHostnameAnnotation,
37✔
160
                dynamicKubeClient:          dynamicKubeClient,
37✔
161
                ingressRouteInformer:       ingressRouteInformer,
37✔
162
                ingressRouteTcpInformer:    ingressRouteTcpInformer,
37✔
163
                ingressRouteUdpInformer:    ingressRouteUdpInformer,
37✔
164
                oldIngressRouteInformer:    oldIngressRouteInformer,
37✔
165
                oldIngressRouteTcpInformer: oldIngressRouteTcpInformer,
37✔
166
                oldIngressRouteUdpInformer: oldIngressRouteUdpInformer,
37✔
167
                kubeClient:                 kubeClient,
37✔
168
                namespace:                  namespace,
37✔
169
                unstructuredConverter:      uc,
37✔
170
        }, nil
37✔
171
}
172

173
func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
36✔
174
        var endpoints []*endpoint.Endpoint
36✔
175

36✔
176
        if ts.ingressRouteInformer != nil {
71✔
177
                ingressRouteEndpoints, err := ts.ingressRouteEndpoints()
35✔
178
                if err != nil {
35✔
179
                        return nil, err
×
180
                }
×
181
                endpoints = append(endpoints, ingressRouteEndpoints...)
35✔
182
        }
183
        if ts.oldIngressRouteInformer != nil {
71✔
184
                oldIngressRouteEndpoints, err := ts.oldIngressRouteEndpoints()
35✔
185
                if err != nil {
35✔
186
                        return nil, err
×
187
                }
×
188
                endpoints = append(endpoints, oldIngressRouteEndpoints...)
35✔
189
        }
190
        if ts.ingressRouteTcpInformer != nil {
71✔
191
                ingressRouteTcpEndpoints, err := ts.ingressRouteTCPEndpoints()
35✔
192
                if err != nil {
35✔
193
                        return nil, err
×
194
                }
×
195
                endpoints = append(endpoints, ingressRouteTcpEndpoints...)
35✔
196
        }
197
        if ts.oldIngressRouteTcpInformer != nil {
71✔
198
                oldIngressRouteTcpEndpoints, err := ts.oldIngressRouteTCPEndpoints()
35✔
199
                if err != nil {
35✔
200
                        return nil, err
×
201
                }
×
202
                endpoints = append(endpoints, oldIngressRouteTcpEndpoints...)
35✔
203
        }
204
        if ts.ingressRouteUdpInformer != nil {
71✔
205
                ingressRouteUdpEndpoints, err := ts.ingressRouteUDPEndpoints()
35✔
206
                if err != nil {
35✔
207
                        return nil, err
×
208
                }
×
209
                endpoints = append(endpoints, ingressRouteUdpEndpoints...)
35✔
210
        }
211
        if ts.oldIngressRouteUdpInformer != nil {
71✔
212
                oldIngressRouteUdpEndpoints, err := ts.oldIngressRouteUDPEndpoints()
35✔
213
                if err != nil {
35✔
214
                        return nil, err
×
215
                }
×
216
                endpoints = append(endpoints, oldIngressRouteUdpEndpoints...)
35✔
217
        }
218

219
        for _, ep := range endpoints {
82✔
220
                sort.Sort(ep.Targets)
46✔
221
        }
46✔
222

223
        return endpoints, nil
36✔
224
}
225

226
// ingressRouteEndpoints extracts endpoints from all IngressRoute objects
227
func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) {
35✔
228
        var endpoints []*endpoint.Endpoint
35✔
229

35✔
230
        irs, err := ts.ingressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
231
        if err != nil {
35✔
232
                return nil, err
×
233
        }
×
234

235
        var ingressRoutes []*IngressRoute
35✔
236
        for _, ingressRouteObj := range irs {
43✔
237
                unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured)
8✔
238
                if !ok {
8✔
239
                        return nil, errors.New("could not convert IngressRoute object to unstructured")
×
240
                }
×
241

242
                ingressRoute := &IngressRoute{}
8✔
243
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
8✔
244
                if err != nil {
8✔
245
                        return nil, err
×
246
                }
×
247
                ingressRoutes = append(ingressRoutes, ingressRoute)
8✔
248
        }
249

250
        ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes)
35✔
251
        if err != nil {
35✔
252
                return nil, fmt.Errorf("failed to filter IngressRoute: %w", err)
×
253
        }
×
254

255
        for _, ingressRoute := range ingressRoutes {
43✔
256
                var targets endpoint.Targets
8✔
257

8✔
258
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...)
8✔
259

8✔
260
                fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name)
8✔
261

8✔
262
                ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets)
8✔
263
                if err != nil {
8✔
264
                        return nil, err
×
265
                }
×
266
                if len(ingressEndpoints) == 0 {
9✔
267
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
268
                        continue
1✔
269
                }
270

271
                log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
7✔
272
                endpoints = append(endpoints, ingressEndpoints...)
7✔
273
        }
274

275
        return endpoints, nil
35✔
276
}
277

278
// ingressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects
279
func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) {
35✔
280
        var endpoints []*endpoint.Endpoint
35✔
281

35✔
282
        irs, err := ts.ingressRouteTcpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
283
        if err != nil {
35✔
284
                return nil, err
×
285
        }
×
286

287
        var ingressRouteTCPs []*IngressRouteTCP
35✔
288
        for _, ingressRouteTCPObj := range irs {
41✔
289
                unstructuredHost, ok := ingressRouteTCPObj.(*unstructured.Unstructured)
6✔
290
                if !ok {
6✔
291
                        return nil, errors.New("could not convert IngressRouteTCP object to unstructured")
×
292
                }
×
293

294
                ingressRouteTCP := &IngressRouteTCP{}
6✔
295
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRouteTCP, nil)
6✔
296
                if err != nil {
6✔
297
                        return nil, err
×
298
                }
×
299
                ingressRouteTCPs = append(ingressRouteTCPs, ingressRouteTCP)
6✔
300
        }
301

302
        ingressRouteTCPs, err = ts.filterIngressRouteTcpByAnnotations(ingressRouteTCPs)
35✔
303
        if err != nil {
35✔
304
                return nil, fmt.Errorf("failed to filter IngressRouteTCP: %w", err)
×
305
        }
×
306

307
        for _, ingressRouteTCP := range ingressRouteTCPs {
41✔
308
                var targets endpoint.Targets
6✔
309

6✔
310
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteTCP.Annotations)...)
6✔
311

6✔
312
                fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name)
6✔
313

6✔
314
                ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets)
6✔
315
                if err != nil {
6✔
316
                        return nil, err
×
317
                }
×
318
                if len(ingressEndpoints) == 0 {
7✔
319
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
320
                        continue
1✔
321
                }
322

323
                log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints)
5✔
324
                endpoints = append(endpoints, ingressEndpoints...)
5✔
325
        }
326

327
        return endpoints, nil
35✔
328
}
329

330
// ingressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects
331
func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) {
35✔
332
        var endpoints []*endpoint.Endpoint
35✔
333

35✔
334
        irs, err := ts.ingressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
335
        if err != nil {
35✔
336
                return nil, err
×
337
        }
×
338

339
        var ingressRouteUDPs []*IngressRouteUDP
35✔
340
        for _, ingressRouteUDPObj := range irs {
38✔
341
                unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured)
3✔
342
                if !ok {
3✔
343
                        return nil, errors.New("could not convert IngressRouteUDP object to unstructured")
×
344
                }
×
345

346
                ingressRoute := &IngressRouteUDP{}
3✔
347
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
3✔
348
                if err != nil {
3✔
349
                        return nil, err
×
350
                }
×
351
                ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute)
3✔
352
        }
353

354
        ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs)
35✔
355
        if err != nil {
35✔
356
                return nil, fmt.Errorf("failed to filter IngressRouteUDP: %w", err)
×
357
        }
×
358

359
        for _, ingressRouteUDP := range ingressRouteUDPs {
38✔
360
                var targets endpoint.Targets
3✔
361

3✔
362
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...)
3✔
363

3✔
364
                fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name)
3✔
365

3✔
366
                ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets)
3✔
367
                if err != nil {
3✔
368
                        return nil, err
×
369
                }
×
370
                if len(ingressEndpoints) == 0 {
4✔
371
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
372
                        continue
1✔
373
                }
374

375
                log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
2✔
376
                endpoints = append(endpoints, ingressEndpoints...)
2✔
377
        }
378

379
        return endpoints, nil
35✔
380
}
381

382
// oldIngressRouteEndpoints extracts endpoints from all IngressRoute objects
383
func (ts *traefikSource) oldIngressRouteEndpoints() ([]*endpoint.Endpoint, error) {
35✔
384
        var endpoints []*endpoint.Endpoint
35✔
385

35✔
386
        irs, err := ts.oldIngressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
387
        if err != nil {
35✔
388
                return nil, err
×
389
        }
×
390

391
        var ingressRoutes []*IngressRoute
35✔
392
        for _, ingressRouteObj := range irs {
43✔
393
                unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured)
8✔
394
                if !ok {
8✔
395
                        return nil, errors.New("could not convert IngressRoute object to unstructured")
×
396
                }
×
397

398
                ingressRoute := &IngressRoute{}
8✔
399
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
8✔
400
                if err != nil {
8✔
401
                        return nil, err
×
402
                }
×
403
                ingressRoutes = append(ingressRoutes, ingressRoute)
8✔
404
        }
405

406
        ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes)
35✔
407
        if err != nil {
35✔
408
                return nil, fmt.Errorf("failed to filter IngressRoute: %w", err)
×
409
        }
×
410

411
        for _, ingressRoute := range ingressRoutes {
43✔
412
                var targets endpoint.Targets
8✔
413

8✔
414
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRoute.Annotations)...)
8✔
415

8✔
416
                fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name)
8✔
417

8✔
418
                ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets)
8✔
419
                if err != nil {
8✔
420
                        return nil, err
×
421
                }
×
422
                if len(ingressEndpoints) == 0 {
9✔
423
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
424
                        continue
1✔
425
                }
426

427
                log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
7✔
428
                endpoints = append(endpoints, ingressEndpoints...)
7✔
429
        }
430

431
        return endpoints, nil
35✔
432
}
433

434
// oldIngressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects
435
func (ts *traefikSource) oldIngressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) {
35✔
436
        var endpoints []*endpoint.Endpoint
35✔
437

35✔
438
        irs, err := ts.oldIngressRouteTcpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
439
        if err != nil {
35✔
440
                return nil, err
×
441
        }
×
442

443
        var ingressRouteTCPs []*IngressRouteTCP
35✔
444
        for _, ingressRouteTCPObj := range irs {
41✔
445
                unstructuredHost, ok := ingressRouteTCPObj.(*unstructured.Unstructured)
6✔
446
                if !ok {
6✔
447
                        return nil, errors.New("could not convert IngressRouteTCP object to unstructured")
×
448
                }
×
449

450
                ingressRouteTCP := &IngressRouteTCP{}
6✔
451
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRouteTCP, nil)
6✔
452
                if err != nil {
6✔
453
                        return nil, err
×
454
                }
×
455
                ingressRouteTCPs = append(ingressRouteTCPs, ingressRouteTCP)
6✔
456
        }
457

458
        ingressRouteTCPs, err = ts.filterIngressRouteTcpByAnnotations(ingressRouteTCPs)
35✔
459
        if err != nil {
35✔
460
                return nil, fmt.Errorf("failed to filter IngressRouteTCP: %w", err)
×
461
        }
×
462

463
        for _, ingressRouteTCP := range ingressRouteTCPs {
41✔
464
                var targets endpoint.Targets
6✔
465

6✔
466
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteTCP.Annotations)...)
6✔
467

6✔
468
                fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name)
6✔
469

6✔
470
                ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets)
6✔
471
                if err != nil {
6✔
472
                        return nil, err
×
473
                }
×
474
                if len(ingressEndpoints) == 0 {
7✔
475
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
476
                        continue
1✔
477
                }
478

479
                log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints)
5✔
480
                endpoints = append(endpoints, ingressEndpoints...)
5✔
481
        }
482

483
        return endpoints, nil
35✔
484
}
485

486
// oldIngressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects
487
func (ts *traefikSource) oldIngressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) {
35✔
488
        var endpoints []*endpoint.Endpoint
35✔
489

35✔
490
        irs, err := ts.oldIngressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
35✔
491
        if err != nil {
35✔
492
                return nil, err
×
493
        }
×
494

495
        var ingressRouteUDPs []*IngressRouteUDP
35✔
496
        for _, ingressRouteUDPObj := range irs {
38✔
497
                unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured)
3✔
498
                if !ok {
3✔
499
                        return nil, errors.New("could not convert IngressRouteUDP object to unstructured")
×
500
                }
×
501

502
                ingressRoute := &IngressRouteUDP{}
3✔
503
                err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
3✔
504
                if err != nil {
3✔
505
                        return nil, err
×
506
                }
×
507
                ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute)
3✔
508
        }
509

510
        ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs)
35✔
511
        if err != nil {
35✔
512
                return nil, fmt.Errorf("failed to filter IngressRouteUDP: %w", err)
×
513
        }
×
514

515
        for _, ingressRouteUDP := range ingressRouteUDPs {
38✔
516
                var targets endpoint.Targets
3✔
517

3✔
518
                targets = append(targets, getTargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...)
3✔
519

3✔
520
                fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name)
3✔
521

3✔
522
                ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets)
3✔
523
                if err != nil {
3✔
524
                        return nil, err
×
525
                }
×
526
                if len(ingressEndpoints) == 0 {
4✔
527
                        log.Debugf("No endpoints could be generated from Host %s", fullname)
1✔
528
                        continue
1✔
529
                }
530

531
                log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
2✔
532
                endpoints = append(endpoints, ingressEndpoints...)
2✔
533
        }
534

535
        return endpoints, nil
35✔
536
}
537

538
// filterIngressRouteByAnnotation filters a list of IngressRoute by a given annotation selector.
539
func (ts *traefikSource) filterIngressRouteByAnnotation(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) {
70✔
540
        labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter)
70✔
541
        if err != nil {
70✔
542
                return nil, err
×
543
        }
×
544
        selector, err := metav1.LabelSelectorAsSelector(labelSelector)
70✔
545
        if err != nil {
70✔
546
                return nil, err
×
547
        }
×
548

549
        // empty filter returns original list
550
        if selector.Empty() {
70✔
551
                return ingressRoutes, nil
×
552
        }
×
553

554
        filteredList := []*IngressRoute{}
70✔
555

70✔
556
        for _, ingressRoute := range ingressRoutes {
86✔
557
                // convert the IngressRoute's annotations to an equivalent label selector
16✔
558
                annotations := labels.Set(ingressRoute.Annotations)
32✔
559

16✔
560
                // include IngressRoute if its annotations match the selector
16✔
561
                if selector.Matches(annotations) {
562
                        filteredList = append(filteredList, ingressRoute)
563
                }
70✔
564
        }
565

566
        return filteredList, nil
567
}
70✔
568

70✔
569
// filterIngressRouteTcpByAnnotations filters a list of IngressRouteTCP by a given annotation selector.
70✔
570
func (ts *traefikSource) filterIngressRouteTcpByAnnotations(ingressRoutes []*IngressRouteTCP) ([]*IngressRouteTCP, error) {
×
571
        labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter)
×
572
        if err != nil {
70✔
573
                return nil, err
70✔
574
        }
×
575
        selector, err := metav1.LabelSelectorAsSelector(labelSelector)
×
576
        if err != nil {
577
                return nil, err
578
        }
70✔
579

×
580
        // empty filter returns original list
×
581
        if selector.Empty() {
582
                return ingressRoutes, nil
70✔
583
        }
70✔
584

82✔
585
        filteredList := []*IngressRouteTCP{}
12✔
586

24✔
587
        for _, ingressRoute := range ingressRoutes {
12✔
588
                // convert the IngressRoute's annotations to an equivalent label selector
12✔
589
                annotations := labels.Set(ingressRoute.Annotations)
590

591
                // include IngressRoute if its annotations match the selector
70✔
592
                if selector.Matches(annotations) {
593
                        filteredList = append(filteredList, ingressRoute)
594
                }
595
        }
70✔
596

70✔
597
        return filteredList, nil
70✔
598
}
×
599

×
600
// filterIngressRouteUdpByAnnotations filters a list of IngressRoute by a given annotation selector.
70✔
601
func (ts *traefikSource) filterIngressRouteUdpByAnnotations(ingressRoutes []*IngressRouteUDP) ([]*IngressRouteUDP, error) {
70✔
602
        labelSelector, err := metav1.ParseToLabelSelector(ts.annotationFilter)
×
603
        if err != nil {
×
604
                return nil, err
605
        }
606
        selector, err := metav1.LabelSelectorAsSelector(labelSelector)
70✔
607
        if err != nil {
×
608
                return nil, err
×
609
        }
610

70✔
611
        // empty filter returns original list
70✔
612
        if selector.Empty() {
76✔
613
                return ingressRoutes, nil
6✔
614
        }
12✔
615

6✔
616
        filteredList := []*IngressRouteUDP{}
6✔
617

618
        for _, ingressRoute := range ingressRoutes {
619
                // convert the IngressRoute's annotations to an equivalent label selector
70✔
620
                annotations := labels.Set(ingressRoute.Annotations)
621

622
                // include IngressRoute if its annotations match the selector
623
                if selector.Matches(annotations) {
16✔
624
                        filteredList = append(filteredList, ingressRoute)
16✔
625
                }
16✔
626
        }
16✔
627

16✔
628
        return filteredList, nil
16✔
629
}
16✔
630

16✔
631
// endpointsFromIngressRoute extracts the endpoints from a IngressRoute object
16✔
632
func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
30✔
633
        var endpoints []*endpoint.Endpoint
14✔
634

20✔
635
        resource := fmt.Sprintf("ingressroute/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
6✔
636

6✔
637
        ttl := getTTLFromAnnotations(ingressRoute.Annotations, resource)
638

639
        providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations)
28✔
640

12✔
641
        if !ts.ignoreHostnameAnnotation {
12✔
642
                hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations)
26✔
643
                for _, hostname := range hostnameList {
32✔
644
                        endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier, resource)...)
18✔
645
                }
18✔
646
        }
18✔
647

18✔
648
        for _, route := range ingressRoute.Spec.Routes {
34✔
649
                match := route.Match
16✔
650

16✔
651
                for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) {
652
                        for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) {
653
                                host = strings.TrimPrefix(host, "`")
654
                                host = strings.TrimSuffix(host, "`")
655

16✔
656
                                // Checking for host = * is required, as Host(`*`) can be set
657
                                if host != "*" && host != "" {
658
                                        endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier, resource)...)
659
                                }
12✔
660
                        }
12✔
661
                }
12✔
662
        }
12✔
663

12✔
664
        return endpoints, nil
12✔
665
}
12✔
666

12✔
667
// endpointsFromIngressRouteTCP extracts the endpoints from a IngressRouteTCP object
12✔
668
func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
22✔
669
        var endpoints []*endpoint.Endpoint
10✔
670

14✔
671
        resource := fmt.Sprintf("ingressroutetcp/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
4✔
672

4✔
673
        ttl := getTTLFromAnnotations(ingressRoute.Annotations, resource)
674

675
        providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations)
22✔
676

10✔
677
        if !ts.ignoreHostnameAnnotation {
10✔
678
                hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations)
22✔
679
                for _, hostname := range hostnameList {
28✔
680
                        endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier, resource)...)
16✔
681
                }
16✔
682
        }
16✔
683

16✔
684
        for _, route := range ingressRoute.Spec.Routes {
16✔
685
                match := route.Match
30✔
686

14✔
687
                for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) {
14✔
688
                        for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) {
689
                                host = strings.TrimPrefix(host, "`")
690
                                host = strings.TrimSuffix(host, "`")
691

692
                                // Checking for host = * is required, as HostSNI(`*`) can be set
12✔
693
                                // in the case of TLS passthrough
694
                                if host != "*" && host != "" {
695
                                        endpoints = append(endpoints, endpointsForHostname(host, targets, ttl, providerSpecific, setIdentifier, resource)...)
696
                                }
6✔
697
                        }
6✔
698
                }
6✔
699
        }
6✔
700

6✔
701
        return endpoints, nil
6✔
702
}
6✔
703

6✔
704
// endpointsFromIngressRouteUDP extracts the endpoints from a IngressRouteUDP object
6✔
705
func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
10✔
706
        var endpoints []*endpoint.Endpoint
4✔
707

10✔
708
        resource := fmt.Sprintf("ingressrouteudp/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
6✔
709

6✔
710
        ttl := getTTLFromAnnotations(ingressRoute.Annotations, resource)
711

712
        providerSpecific, setIdentifier := getProviderSpecificAnnotations(ingressRoute.Annotations)
6✔
713

714
        if !ts.ignoreHostnameAnnotation {
715
                hostnameList := getHostnamesFromAnnotations(ingressRoute.Annotations)
×
716
                for _, hostname := range hostnameList {
×
717
                        endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific, setIdentifier, resource)...)
×
718
                }
×
719
        }
×
720

×
721
        return endpoints, nil
×
722
}
×
723

×
724
func (ts *traefikSource) AddEventHandler(ctx context.Context, handler func()) {
×
725
        // Right now there is no way to remove event handler from informer, see:
×
726
        // https://github.com/kubernetes/kubernetes/issues/79610
×
727
        log.Debug("Adding event handler for IngressRoute")
×
728
        if ts.ingressRouteInformer != nil {
×
729
                ts.ingressRouteInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
×
730
        }
×
731
        if ts.oldIngressRouteInformer != nil {
×
732
                ts.oldIngressRouteInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
×
733
        }
×
734
        log.Debug("Adding event handler for IngressRouteTCP")
×
735
        if ts.ingressRouteTcpInformer != nil {
×
736
                ts.ingressRouteTcpInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
×
737
        }
×
738
        if ts.oldIngressRouteTcpInformer != nil {
×
739
                ts.oldIngressRouteTcpInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
740
        }
741
        log.Debug("Adding event handler for IngressRouteUDP")
742
        if ts.ingressRouteUdpInformer != nil {
37✔
743
                ts.ingressRouteUdpInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
37✔
744
        }
37✔
745
        if ts.oldIngressRouteUdpInformer != nil {
37✔
746
                ts.oldIngressRouteUdpInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
37✔
747
        }
37✔
748
}
37✔
749

37✔
750
// newTraefikUnstructuredConverter returns a new unstructuredConverter initialized
37✔
751
func newTraefikUnstructuredConverter() (*unstructuredConverter, error) {
37✔
752
        uc := &unstructuredConverter{
37✔
753
                scheme: runtime.NewScheme(),
37✔
754
        }
37✔
755

×
756
        // Add the core types we need
×
757
        uc.scheme.AddKnownTypes(ingressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{})
758
        uc.scheme.AddKnownTypes(oldIngressrouteGVR.GroupVersion(), &IngressRoute{}, &IngressRouteList{})
37✔
759
        uc.scheme.AddKnownTypes(ingressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{})
760
        uc.scheme.AddKnownTypes(oldIngressrouteTCPGVR.GroupVersion(), &IngressRouteTCP{}, &IngressRouteTCPList{})
761
        uc.scheme.AddKnownTypes(ingressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{})
762
        uc.scheme.AddKnownTypes(oldIngressrouteUDPGVR.GroupVersion(), &IngressRouteUDP{}, &IngressRouteUDPList{})
763
        if err := scheme.AddToScheme(uc.scheme); err != nil {
764
                return nil, err
765
        }
766

767
        return uc, nil
768
}
769

770
// Basic redefinition of Traefik 2's CRD: https://github.com/traefik/traefik/tree/v2.8.7/pkg/provider/kubernetes/crd/traefik/v1alpha1
771

772
// traefikIngressRouteSpec defines the desired state of IngressRoute.
773
type traefikIngressRouteSpec struct {
774
        // Routes defines the list of routes.
775
        Routes []traefikRoute `json:"routes"`
776
}
777

778
// traefikRoute holds the HTTP route configuration.
779
type traefikRoute struct {
780
        // Match defines the router's rule.
781
        // More info: https://doc.traefik.io/traefik/v2.9/routing/routers/#rule
782
        Match string `json:"match"`
783
}
784

785
// IngressRoute is the CRD implementation of a Traefik HTTP Router.
786
type IngressRoute struct {
787
        metav1.TypeMeta `json:",inline"`
788
        // Standard object's metadata.
789
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
790
        metav1.ObjectMeta `json:"metadata"`
791

792
        Spec traefikIngressRouteSpec `json:"spec"`
793
}
794

795
// IngressRouteList is a collection of IngressRoute.
796
type IngressRouteList struct {
797
        metav1.TypeMeta `json:",inline"`
798
        // Standard object's metadata.
799
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
800
        metav1.ListMeta `json:"metadata"`
801

802
        // Items is the list of IngressRoute.
803
        Items []IngressRoute `json:"items"`
804
}
805

806
// traefikIngressRouteTCPSpec defines the desired state of IngressRouteTCP.
807
type traefikIngressRouteTCPSpec struct {
808
        Routes []traefikRouteTCP `json:"routes"`
809
}
810

811
// traefikRouteTCP holds the TCP route configuration.
812
type traefikRouteTCP struct {
813
        // Match defines the router's rule.
814
        // More info: https://doc.traefik.io/traefik/v2.9/routing/routers/#rule_1
815
        Match string `json:"match"`
816
}
817

818
// IngressRouteTCP is the CRD implementation of a Traefik TCP Router.
819
type IngressRouteTCP struct {
820
        metav1.TypeMeta `json:",inline"`
821
        // Standard object's metadata.
822
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
823
        metav1.ObjectMeta `json:"metadata"`
824

825
        Spec traefikIngressRouteTCPSpec `json:"spec"`
826
}
827

828
// IngressRouteTCPList is a collection of IngressRouteTCP.
829
type IngressRouteTCPList struct {
830
        metav1.TypeMeta `json:",inline"`
831
        // Standard object's metadata.
832
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
833
        metav1.ListMeta `json:"metadata"`
834

835
        // Items is the list of IngressRouteTCP.
836
        Items []IngressRouteTCP `json:"items"`
837
}
838

839
// IngressRouteUDP is a CRD implementation of a Traefik UDP Router.
840
type IngressRouteUDP struct {
841
        metav1.TypeMeta `json:",inline"`
842
        // Standard object's metadata.
843
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
844
        metav1.ObjectMeta `json:"metadata"`
845
}
846

847
// IngressRouteUDPList is a collection of IngressRouteUDP.
848
type IngressRouteUDPList struct {
849
        metav1.TypeMeta `json:",inline"`
850
        // Standard object's metadata.
16✔
851
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
16✔
852
        metav1.ListMeta `json:"metadata"`
16✔
853

16✔
854
        // Items is the list of IngressRouteUDP.
16✔
855
        Items []IngressRouteUDP `json:"items"`
16✔
856
}
857

858
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
859
func (in *IngressRoute) DeepCopyInto(out *IngressRoute) {
×
860
        *out = *in
×
861
        out.TypeMeta = in.TypeMeta
×
862
        in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
×
863
        in.Spec.DeepCopyInto(&out.Spec)
×
864
}
×
865

866
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRoute.
867
func (in *IngressRoute) DeepCopy() *IngressRoute {
868
        if in == nil {
×
869
                return nil
×
870
        }
×
871
        out := new(IngressRoute)
×
872
        in.DeepCopyInto(out)
×
873
        return out
874
}
875

876
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
×
877
func (in *IngressRoute) DeepCopyObject() runtime.Object {
×
878
        if c := in.DeepCopy(); c != nil {
×
879
                return c
×
880
        }
×
881
        return nil
×
882
}
×
883

×
884
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
885
func (in *IngressRouteList) DeepCopyInto(out *IngressRouteList) {
×
886
        *out = *in
887
        out.TypeMeta = in.TypeMeta
888
        in.ListMeta.DeepCopyInto(&out.ListMeta)
889
        if in.Items != nil {
890
                in, out := &in.Items, &out.Items
×
891
                *out = make([]IngressRoute, len(*in))
×
892
                for i := range *in {
×
893
                        (*in)[i].DeepCopyInto(&(*out)[i])
×
894
                }
×
895
        }
×
896
}
×
897

898
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteList.
899
func (in *IngressRouteList) DeepCopy() *IngressRouteList {
900
        if in == nil {
×
901
                return nil
×
902
        }
×
903
        out := new(IngressRouteList)
×
904
        in.DeepCopyInto(out)
×
905
        return out
906
}
907

908
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
16✔
909
func (in *IngressRouteList) DeepCopyObject() runtime.Object {
16✔
910
        if c := in.DeepCopy(); c != nil {
28✔
911
                return c
12✔
912
        }
12✔
913
        return nil
24✔
914
}
12✔
915

12✔
916
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
917
func (in *traefikIngressRouteSpec) DeepCopyInto(out *traefikIngressRouteSpec) {
918
        *out = *in
919
        if in.Routes != nil {
920
                in, out := &in.Routes, &out.Routes
×
921
                *out = make([]traefikRoute, len(*in))
×
922
                for i := range *in {
×
923
                        (*in)[i].DeepCopyInto(&(*out)[i])
×
924
                }
×
925
        }
×
926
}
×
927

928
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteSpec.
929
func (in *traefikIngressRouteSpec) DeepCopy() *traefikIngressRouteSpec {
930
        if in == nil {
12✔
931
                return nil
12✔
932
        }
12✔
933
        out := new(traefikIngressRouteSpec)
934
        in.DeepCopyInto(out)
935
        return out
×
936
}
×
937

×
938
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
939
func (in *traefikRoute) DeepCopyInto(out *traefikRoute) {
×
940
        *out = *in
×
941
}
×
942

943
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route.
944
func (in *traefikRoute) DeepCopy() *traefikRoute {
945
        if in == nil {
12✔
946
                return nil
12✔
947
        }
12✔
948
        out := new(traefikRoute)
12✔
949
        in.DeepCopyInto(out)
12✔
950
        return out
12✔
951
}
952

953
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
954
func (in *IngressRouteTCP) DeepCopyInto(out *IngressRouteTCP) {
×
955
        *out = *in
×
956
        out.TypeMeta = in.TypeMeta
×
957
        in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
×
958
        in.Spec.DeepCopyInto(&out.Spec)
×
959
}
×
960

961
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCP.
962
func (in *IngressRouteTCP) DeepCopy() *IngressRouteTCP {
963
        if in == nil {
×
964
                return nil
×
965
        }
×
966
        out := new(IngressRouteTCP)
×
967
        in.DeepCopyInto(out)
×
968
        return out
969
}
970

971
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
×
972
func (in *IngressRouteTCP) DeepCopyObject() runtime.Object {
×
973
        if c := in.DeepCopy(); c != nil {
×
974
                return c
×
975
        }
×
976
        return nil
×
977
}
×
978

×
979
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
980
func (in *IngressRouteTCPList) DeepCopyInto(out *IngressRouteTCPList) {
×
981
        *out = *in
982
        out.TypeMeta = in.TypeMeta
983
        in.ListMeta.DeepCopyInto(&out.ListMeta)
984
        if in.Items != nil {
985
                in, out := &in.Items, &out.Items
×
986
                *out = make([]IngressRouteTCP, len(*in))
×
987
                for i := range *in {
×
988
                        (*in)[i].DeepCopyInto(&(*out)[i])
×
989
                }
×
990
        }
×
991
}
×
992

993
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPList.
994
func (in *IngressRouteTCPList) DeepCopy() *IngressRouteTCPList {
995
        if in == nil {
×
996
                return nil
×
997
        }
×
998
        out := new(IngressRouteTCPList)
×
999
        in.DeepCopyInto(out)
×
1000
        return out
1001
}
1002

1003
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
12✔
1004
func (in *IngressRouteTCPList) DeepCopyObject() runtime.Object {
12✔
1005
        if c := in.DeepCopy(); c != nil {
22✔
1006
                return c
10✔
1007
        }
10✔
1008
        return nil
20✔
1009
}
10✔
1010

10✔
1011
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
1012
func (in *traefikIngressRouteTCPSpec) DeepCopyInto(out *traefikIngressRouteTCPSpec) {
1013
        *out = *in
1014
        if in.Routes != nil {
1015
                in, out := &in.Routes, &out.Routes
×
1016
                *out = make([]traefikRouteTCP, len(*in))
×
1017
                for i := range *in {
×
1018
                        (*in)[i].DeepCopyInto(&(*out)[i])
×
1019
                }
×
1020
        }
×
1021
}
×
1022

1023
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteTCPSpec.
1024
func (in *traefikIngressRouteTCPSpec) DeepCopy() *traefikIngressRouteTCPSpec {
1025
        if in == nil {
10✔
1026
                return nil
10✔
1027
        }
10✔
1028
        out := new(traefikIngressRouteTCPSpec)
1029
        in.DeepCopyInto(out)
1030
        return out
×
1031
}
×
1032

×
1033
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
1034
func (in *traefikRouteTCP) DeepCopyInto(out *traefikRouteTCP) {
×
1035
        *out = *in
×
1036
}
×
1037

1038
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTCP.
1039
func (in *traefikRouteTCP) DeepCopy() *traefikRouteTCP {
1040
        if in == nil {
6✔
1041
                return nil
6✔
1042
        }
6✔
1043
        out := new(traefikRouteTCP)
6✔
1044
        in.DeepCopyInto(out)
6✔
1045
        return out
1046
}
1047

×
1048
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
1049
func (in *IngressRouteUDP) DeepCopyInto(out *IngressRouteUDP) {
×
1050
        *out = *in
×
1051
        out.TypeMeta = in.TypeMeta
×
1052
        in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
×
1053
}
×
1054

1055
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteUDP.
1056
func (in *IngressRouteUDP) DeepCopy() *IngressRouteUDP {
1057
        if in == nil {
×
1058
                return nil
×
1059
        }
×
1060
        out := new(IngressRouteUDP)
×
1061
        in.DeepCopyInto(out)
×
1062
        return out
1063
}
1064

1065
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
×
1066
func (in *IngressRouteUDP) DeepCopyObject() runtime.Object {
×
1067
        if c := in.DeepCopy(); c != nil {
×
1068
                return c
×
1069
        }
×
1070
        return nil
×
1071
}
×
1072

×
1073
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
×
1074
func (in *IngressRouteUDPList) DeepCopyInto(out *IngressRouteUDPList) {
×
1075
        *out = *in
1076
        out.TypeMeta = in.TypeMeta
1077
        in.ListMeta.DeepCopyInto(&out.ListMeta)
1078
        if in.Items != nil {
1079
                in, out := &in.Items, &out.Items
×
1080
                *out = make([]IngressRouteUDP, len(*in))
×
1081
                for i := range *in {
×
1082
                        (*in)[i].DeepCopyInto(&(*out)[i])
×
1083
                }
×
1084
        }
×
1085
}
×
1086

1087
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRouteUDPList.
1088
func (in *IngressRouteUDPList) DeepCopy() *IngressRouteUDPList {
1089
        if in == nil {
×
1090
                return nil
×
1091
        }
×
1092
        out := new(IngressRouteUDPList)
×
1093
        in.DeepCopyInto(out)
×
1094
        return out
1095
}
1096

1097
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
1098
func (in *IngressRouteUDPList) DeepCopyObject() runtime.Object {
1099
        if c := in.DeepCopy(); c != nil {
1100
                return c
1101
        }
1102
        return nil
1103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc