@@ -6,10 +6,152 @@ package app
66
77import (
88 "context"
9+ "fmt"
10+ "slices"
911
1012 "github.com/go-logr/logr"
13+ corev1 "k8s.io/api/core/v1"
14+ apierrors "k8s.io/apimachinery/pkg/api/errors"
15+ "sigs.k8s.io/controller-runtime/pkg/client"
16+
17+ v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
18+ resourcesv1alpha1 "github.com/gardener/gardener/pkg/apis/resources/v1alpha1"
19+ "github.com/gardener/gardener/pkg/client/kubernetes"
20+ gardeneraccess "github.com/gardener/gardener/pkg/component/gardener/access"
21+ shootsystem "github.com/gardener/gardener/pkg/component/shoot/system"
22+ "github.com/gardener/gardener/pkg/utils/flow"
23+ "github.com/gardener/gardener/pkg/utils/managedresources"
1124)
1225
13- func (g * garden ) runMigrations (_ context.Context , _ logr.Logger ) error {
26+ func (g * garden ) runMigrations (ctx context.Context , log logr.Logger ) error {
27+ log .Info ("Migrating ClusterRoleBindings for shoot/adminkubeconfig and shoot/viewerkubeconfig" )
28+ if err := migrateAdminViewerKubeconfigClusterRoleBindings (ctx , log , g .mgr .GetClient ()); err != nil {
29+ return fmt .Errorf ("failed migrating ClusterRoleBindings for shoot/adminkubeconfig and shoot/viewerkubeconfig: %w" , err )
30+ }
31+
1432 return nil
1533}
34+
35+ // migrateAdminViewerKubeconfigClusterRoleBindings moves the ClusterRoleBindings granting access to the
36+ // shoot/adminkubeconfig and shoot/viewerkubeconfig subresources from the shoot-core-system managed resource to the
37+ // shoot-core-gardeneraccess managed resource.
38+ // TODO(vpnachev): Remove this after v1.133.0 has been released.
39+ func migrateAdminViewerKubeconfigClusterRoleBindings (ctx context.Context , log logr.Logger , seedClient client.Client ) error {
40+ namespaceList := & corev1.NamespaceList {}
41+ if err := seedClient .List (ctx , namespaceList , client.MatchingLabels {v1beta1constants .GardenRole : v1beta1constants .GardenRoleShoot }); err != nil {
42+ return fmt .Errorf ("failed listing namespaces: %w" , err )
43+ }
44+
45+ var (
46+ tasks []flow.TaskFn
47+ crbs = []string {v1beta1constants .ShootProjectAdminsGroupName , v1beta1constants .ShootProjectViewersGroupName , v1beta1constants .ShootSystemAdminsGroupName , v1beta1constants .ShootSystemViewersGroupName }
48+ )
49+
50+ for _ , namespace := range namespaceList .Items {
51+ if namespace .DeletionTimestamp != nil || namespace .Status .Phase == corev1 .NamespaceTerminating {
52+ continue
53+ }
54+
55+ tasks = append (tasks , func (ctx context.Context ) error {
56+ var (
57+ shootSystemKey = client.ObjectKey {Namespace : namespace .Name , Name : shootsystem .ManagedResourceName }
58+ shootSystemManagedResource = & resourcesv1alpha1.ManagedResource {}
59+
60+ gardenerAccessKey = client.ObjectKey {Namespace : namespace .Name , Name : gardeneraccess .ManagedResourceName }
61+ gardenerAccessManagedResource = & resourcesv1alpha1.ManagedResource {}
62+ )
63+
64+ // Get the shoot-core-system managed resource and check if it is already migrated.
65+ if err := seedClient .Get (ctx , shootSystemKey , shootSystemManagedResource ); err != nil {
66+ if apierrors .IsNotFound (err ) {
67+ log .Info ("Managed resource not found, skipping migration" , "managedResource" , shootSystemKey )
68+ return nil
69+ }
70+ return fmt .Errorf ("failed to get ManagedResource %q: %w" , shootSystemKey , err )
71+ }
72+
73+ if shootSystemManagedResource .DeletionTimestamp != nil {
74+ log .Info ("Managed resource is in deletion, skipping migration" , "managedResource" , shootSystemKey )
75+ return nil
76+ }
77+
78+ shootSystemObjects , err := managedresources .GetObjects (ctx , seedClient , shootSystemManagedResource .Namespace , shootSystemManagedResource .Name )
79+ if err != nil {
80+ if apierrors .IsNotFound (err ) {
81+ log .Info ("Managed resource secret not found, skipping migration" , "managedResource" , shootSystemKey )
82+ return nil
83+ }
84+ return fmt .Errorf ("failed to get objects for ManagedResource %q: %w" , shootSystemKey , err )
85+ }
86+
87+ oldShootSystemObjectsCount := len (shootSystemObjects )
88+ shootSystemObjects = slices .DeleteFunc (shootSystemObjects , func (obj client.Object ) bool {
89+ return slices .Contains (crbs , obj .GetName ())
90+ })
91+
92+ if oldShootSystemObjectsCount == len (shootSystemObjects ) {
93+ log .Info ("ClusterRoleBindings for shoot/adminkubeconfig and shoot/viewerkubeconfig have already been migrated, skipping migration" , "managedResource" , shootSystemKey )
94+ return nil
95+ }
96+
97+ // Move the ClusterRoleBindings to the shoot-core-gardeneraccess managed resource firstly.
98+ if err := seedClient .Get (ctx , gardenerAccessKey , gardenerAccessManagedResource ); err != nil {
99+ if apierrors .IsNotFound (err ) {
100+ log .Info ("Managed resource not found, skipping migration" , "managedResource" , gardenerAccessKey )
101+ return nil
102+ }
103+ return fmt .Errorf ("failed to get ManagedResource %q: %w" , gardenerAccessKey , err )
104+ }
105+
106+ if gardenerAccessManagedResource .DeletionTimestamp != nil {
107+ log .Info ("Managed resource is in deletion, skipping migration" , "managedResource" , gardenerAccessKey )
108+ return nil
109+ }
110+
111+ gardenerAccessObjects , err := managedresources .GetObjects (ctx , seedClient , gardenerAccessManagedResource .Namespace , gardenerAccessManagedResource .Name )
112+ if err != nil {
113+ if apierrors .IsNotFound (err ) {
114+ log .Info ("Managed resource secret not found, skipping migration" , "managedResource" , gardenerAccessKey )
115+ return nil
116+ }
117+ return fmt .Errorf ("failed to get objects for ManagedResource %q: %w" , gardenerAccessKey , err )
118+ }
119+
120+ gardenerAccessObjects = append (gardenerAccessObjects , gardeneraccess .ShootAccessClusterRoleBindings ()... )
121+ gardenerAccessRegistry := managedresources .NewRegistry (kubernetes .ShootScheme , kubernetes .ShootCodec , kubernetes .ShootSerializer )
122+ gardenerAccessResources , err := gardenerAccessRegistry .AddAllAndSerialize (gardenerAccessObjects ... )
123+ if err != nil {
124+ return fmt .Errorf ("failed serializing objects for ManagedResource %q: %w" , gardenerAccessKey , err )
125+ }
126+
127+ if err := managedresources .CreateForShoot (ctx , seedClient , gardenerAccessManagedResource .Namespace , gardenerAccessManagedResource .Name , managedresources .LabelValueGardener , false , gardenerAccessResources ); err != nil {
128+ return fmt .Errorf ("failed updating ManagedResource %q: %w" , gardenerAccessKey , err )
129+ }
130+
131+ // Remove the ClusterRoleBindings from the shoot-core-system managed resource.
132+ log .Info ("Updating ManagedResource status to remove migrated ClusterRoleBindings" , "managedResource" , shootSystemKey )
133+ patch := client .MergeFrom (shootSystemManagedResource .DeepCopy ())
134+ shootSystemManagedResource .Status .Resources = slices .DeleteFunc (shootSystemManagedResource .Status .Resources , func (objRef resourcesv1alpha1.ObjectReference ) bool {
135+ return objRef .APIVersion == "rbac.authorization.k8s.io/v1" && objRef .Kind == "ClusterRoleBinding" && slices .Contains (crbs , objRef .Name )
136+ })
137+
138+ if err := seedClient .Status ().Patch (ctx , shootSystemManagedResource , patch ); err != nil {
139+ return fmt .Errorf ("failed updating status of ManagedResource %q: %w" , shootSystemKey , err )
140+ }
141+
142+ log .Info ("Cleaning ClusterRoleBindings for shoot/adminkubeconfig and shoot/viewerkubeconfig access in managed resource" , "managedResource" , shootSystemKey )
143+ shootSystemRegistry := managedresources .NewRegistry (kubernetes .ShootScheme , kubernetes .ShootCodec , kubernetes .ShootSerializer )
144+ shootSystemResources , err := shootSystemRegistry .AddAllAndSerialize (shootSystemObjects ... )
145+ if err != nil {
146+ return fmt .Errorf ("failed serializing objects for ManagedResource %q: %w" , shootSystemKey , err )
147+ }
148+ if err := managedresources .CreateForShoot (ctx , seedClient , shootSystemManagedResource .Namespace , shootSystemManagedResource .Name , managedresources .LabelValueGardener , false , shootSystemResources ); err != nil {
149+ return fmt .Errorf ("failed updating ManagedResource %q: %w" , shootSystemKey , err )
150+ }
151+
152+ return nil
153+ })
154+ }
155+
156+ return flow .Parallel (tasks ... )(ctx )
157+ }
0 commit comments