-
Notifications
You must be signed in to change notification settings - Fork 463
/
add.go
140 lines (122 loc) · 5.09 KB
/
add.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
package backupentry
import (
"context"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/clock"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/cluster"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
gardencore "github.com/gardener/gardener/pkg/apis/core"
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
"github.com/gardener/gardener/pkg/controllerutils/mapper"
predicateutils "github.com/gardener/gardener/pkg/controllerutils/predicate"
"github.com/gardener/gardener/pkg/extensions"
gardenerutils "github.com/gardener/gardener/pkg/utils/gardener"
kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes"
)
// ControllerName is the name of this controller.
const ControllerName = "backupentry"
// AddToManager adds Reconciler to the given manager.
func (r *Reconciler) AddToManager(ctx context.Context, mgr manager.Manager, gardenCluster, seedCluster cluster.Cluster) error {
if r.GardenClient == nil {
r.GardenClient = gardenCluster.GetClient()
}
if r.SeedClient == nil {
r.SeedClient = seedCluster.GetClient()
}
if r.Clock == nil {
r.Clock = clock.RealClock{}
}
if r.Recorder == nil {
r.Recorder = gardenCluster.GetEventRecorderFor(ControllerName + "-controller")
}
if r.GardenNamespace == "" {
r.GardenNamespace = v1beta1constants.GardenNamespace
}
c, err := builder.
ControllerManagedBy(mgr).
Named(ControllerName).
WithOptions(controller.Options{
MaxConcurrentReconciles: ptr.Deref(r.Config.ConcurrentSyncs, 0),
RateLimiter: r.RateLimiter,
}).
WatchesRawSource(
source.Kind(gardenCluster.GetCache(), &gardencorev1beta1.BackupEntry{}),
&handler.EnqueueRequestForObject{},
builder.WithPredicates(
&predicate.GenerationChangedPredicate{},
predicateutils.SeedNamePredicate(r.SeedName, gardenerutils.GetBackupEntrySeedNames),
),
).
Build(r)
if err != nil {
return err
}
if err := c.Watch(
source.Kind(gardenCluster.GetCache(), &gardencorev1beta1.BackupBucket{}),
mapper.EnqueueRequestsFrom(ctx, mgr.GetCache(), mapper.MapFunc(r.MapBackupBucketToBackupEntry), mapper.UpdateWithNew, c.GetLogger()),
predicateutils.LastOperationChanged(getBackupBucketLastOperation),
); err != nil {
return err
}
return c.Watch(
source.Kind(seedCluster.GetCache(), &extensionsv1alpha1.BackupEntry{}),
mapper.EnqueueRequestsFrom(ctx, mgr.GetCache(), mapper.MapFunc(r.MapExtensionBackupEntryToCoreBackupEntry), mapper.UpdateWithNew, c.GetLogger()),
predicateutils.LastOperationChanged(predicateutils.GetExtensionLastOperation),
)
}
// MapBackupBucketToBackupEntry is a mapper.MapFunc for mapping a core.gardener.cloud/v1beta1.BackupBucket to the
// core.gardener.cloud/v1beta1.BackupEntry that references it..
func (r *Reconciler) MapBackupBucketToBackupEntry(ctx context.Context, log logr.Logger, _ client.Reader, obj client.Object) []reconcile.Request {
backupBucket, ok := obj.(*gardencorev1beta1.BackupBucket)
if !ok {
return nil
}
backupEntryList := &gardencorev1beta1.BackupEntryList{}
if err := r.GardenClient.List(ctx, backupEntryList, client.MatchingFields{gardencore.BackupEntryBucketName: backupBucket.Name}); err != nil {
log.Error(err, "Failed to list backupentries referencing this bucket", "backupBucketName", backupBucket.Name)
return nil
}
return mapper.ObjectListToRequests(backupEntryList)
}
// MapExtensionBackupEntryToCoreBackupEntry is a mapper.MapFunc for mapping a extensions.gardener.cloud/v1alpha1.BackupEntry to the owning
// core.gardener.cloud/v1beta1.BackupEntry.
func (r *Reconciler) MapExtensionBackupEntryToCoreBackupEntry(ctx context.Context, log logr.Logger, _ client.Reader, obj client.Object) []reconcile.Request {
if obj.GetDeletionTimestamp() != nil {
return nil
}
shootTechnicalID, _ := gardenerutils.ExtractShootDetailsFromBackupEntryName(obj.GetName())
if shootTechnicalID == "" {
return nil
}
shoot, err := extensions.GetShoot(ctx, r.SeedClient, shootTechnicalID)
if err != nil {
log.Error(err, "Failed to get shoot from cluster", "shootTechnicalID", shootTechnicalID)
return nil
}
if shoot == nil {
log.Info("Shoot is missing in cluster resource", "cluster", kubernetesutils.Key(shootTechnicalID))
return nil
}
return []reconcile.Request{{NamespacedName: types.NamespacedName{Name: obj.GetName(), Namespace: shoot.Namespace}}}
}
func getBackupBucketLastOperation(obj client.Object) *gardencorev1beta1.LastOperation {
backupBucket, ok := obj.(*gardencorev1beta1.BackupBucket)
if !ok {
return nil
}
return backupBucket.Status.LastOperation
}