@@ -33,6 +33,7 @@ import (
3333 kmapi "kmodules.xyz/client-go/api/v1"
3434 kmc "kmodules.xyz/client-go/client"
3535 "kmodules.xyz/client-go/meta"
36+ sidekickapi "kubeops.dev/sidekick/apis/apps/v1alpha1"
3637 "sigs.k8s.io/controller-runtime/pkg/client"
3738)
3839
@@ -52,6 +53,9 @@ const (
5253 AzureSubscriptionIDAnnotation = "klusters.dev/azure-subscription-id"
5354 AzureMIClientIDAnnotation = "azure.workload.identity/client-id"
5455 AzureMITenantIDAnnotation = "azure.workload.identity/tenant-id"
56+
57+ AzureWorkloadIdentityUseLabel = "azure.workload.identity/use"
58+ AzureWorkloadIdentityUseAnnotation = "azure.workload.identity/use-identity-binding"
5559)
5660
5761func GetCloudAnnotations (ctx context.Context , kc client.Client , storages ... storageapi.BackupStorage ) (map [string ]string , error ) {
@@ -139,12 +143,20 @@ func setBucketAnnotations(annotations map[string]string, storages ...storageapi.
139143}
140144
141145func AddCloudAnnotationsToSAIfNeeded (ctx context.Context , kbClient client.Client ,
142- bs * storageapi.BackupStorage , saRef * kmapi. ObjectReference , invTypRef * core.TypedObjectReference ,
146+ bs * storageapi.BackupStorage , sidekick * sidekickapi. Sidekick , invTypRef * core.TypedObjectReference ,
143147) (bool , error ) {
144- sa , err := getServiceAccount (ctx , kbClient , saRef )
148+ sa , err := getServiceAccount (ctx , kbClient , & kmapi.ObjectReference {
149+ Name : sidekick .Spec .ServiceAccountName ,
150+ Namespace : sidekick .Namespace ,
151+ })
145152 if err != nil {
146153 return true , fmt .Errorf ("failed to get service account: %v" , err )
147154 }
155+
156+ if bs .IsCredentialLessModeEnabled () {
157+ addSidekickAnnotationsIfNeeded (sidekick , bs )
158+ }
159+
148160 if ! isCloudAnnotationNeeded (bs , sa ) { // Return if not needed
149161 return false , nil
150162 }
@@ -168,11 +180,28 @@ func AddCloudAnnotationsToSAIfNeeded(ctx context.Context, kbClient client.Client
168180 return false , nil
169181}
170182
183+ func addSidekickAnnotationsIfNeeded (sidekick * sidekickapi.Sidekick , bs * storageapi.BackupStorage ) {
184+ if bs .Spec .Storage .Provider == storageapi .ProviderAzure {
185+ if sidekick .Labels == nil {
186+ sidekick .Labels = make (map [string ]string )
187+ }
188+ sidekick .Labels [AzureWorkloadIdentityUseLabel ] = "true"
189+ if sidekick .Annotations == nil {
190+ sidekick .Annotations = make (map [string ]string )
191+ }
192+ sidekick .Annotations [AzureWorkloadIdentityUseAnnotation ] = "true"
193+ }
194+ }
195+
171196func hasCredLessManagerProvidedAnnotation (bs * storageapi.BackupStorage , sa * core.ServiceAccount ) bool {
172197 switch bs .Spec .Storage .Provider {
173198 case storageapi .ProviderS3 :
174199 _ , exists := sa .Annotations [AWSIRSARoleAnnotation ]
175200 return exists
201+ case storageapi .ProviderAzure :
202+ _ , hasClientId := sa .Annotations [AzureMIClientIDAnnotation ]
203+ _ , hasTenantId := sa .Annotations [AzureMITenantIDAnnotation ]
204+ return hasClientId && hasTenantId
176205 default :
177206 return false
178207 }
@@ -184,7 +213,10 @@ func isCloudAnnotationNeeded(bs *storageapi.BackupStorage, sa *core.ServiceAccou
184213 case storageapi .ProviderS3 :
185214 _ , ok := sa .Annotations [AWSSeedRoleAnnotationName ]
186215 return ! ok
187- // case storageapi.ProviderAzure:
216+ case storageapi .ProviderAzure :
217+ _ , hasClientId := sa .Annotations [AzureMIClientIDAnnotation ]
218+ _ , hasTenantId := sa .Annotations [AzureMITenantIDAnnotation ]
219+ return ! hasTenantId || ! hasClientId
188220 }
189221 }
190222 return false
@@ -260,6 +292,10 @@ func hasRequiredCloudAnnotations(bs *storageapi.BackupStorage, sa *core.ServiceA
260292 if bs .Spec .Storage .Provider == storageapi .ProviderS3 {
261293 return sa .Annotations [AWSSeedRoleAnnotationName ] != "" && sa .Annotations [BucketAnnotationKey ] != ""
262294 }
295+ if bs .Spec .Storage .Provider == storageapi .ProviderAzure {
296+ return sa .Annotations [AzureSubscriptionIDAnnotation ] != "" && sa .Annotations [AzureMINameAnnotation ] != "" &&
297+ sa .Annotations [AzureResourceGroupAnnotation ] != ""
298+ }
263299 return false
264300}
265301
@@ -431,12 +467,28 @@ func getAWSAnnotations(source map[string]string) (map[string]string, error) {
431467 return annotations , nil
432468}
433469
470+ func getAzureAnnotations (source map [string ]string ) (map [string ]string , error ) {
471+ required := map [string ]string {
472+ AzureSubscriptionIDAnnotation : source [AzureSubscriptionIDAnnotation ],
473+ AzureMINameAnnotation : source [AzureMINameAnnotation ],
474+ AzureResourceGroupAnnotation : source [AzureResourceGroupAnnotation ],
475+ BucketAnnotationKey : source [BucketAnnotationKey ],
476+ }
477+ annotations := make (map [string ]string )
478+ for key , val := range required {
479+ annotations [key ] = val
480+ }
481+ return annotations , nil
482+ }
483+
434484func getRequiredAnnotations (bs * storageapi.BackupStorage , annotations map [string ]string ) (map [string ]string , error ) {
435485 switch bs .Spec .Storage .Provider {
436486 case storageapi .ProviderS3 :
437487 return getAWSAnnotations (annotations )
438488 // case storageapi.ProviderGCS:
439489 // return applyGCPAnnotations(sa, annotations)
490+ case storageapi .ProviderAzure :
491+ return getAzureAnnotations (annotations )
440492 default :
441493 return nil , fmt .Errorf ("unsupported storage provider: %s" , bs .Spec .Storage .Provider )
442494
0 commit comments