Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
kmodules.xyz/offshoot-api v0.34.0
kmodules.xyz/prober v0.34.0
kubedb.dev/apimachinery v0.63.0
kubestash.dev/apimachinery v0.27.0
kubestash.dev/apimachinery v0.28.0-rc.0
sigs.k8s.io/controller-runtime v0.22.4
sigs.k8s.io/yaml v1.6.0
stash.appscode.dev/apimachinery v0.42.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -914,8 +914,8 @@ kubeops.dev/petset v0.0.15 h1:iwTRFAp0RNw0A87sw2c97UZ6WIA9H/nhJBpDhXLa7fk=
kubeops.dev/petset v0.0.15/go.mod h1:sw96WiXfzhpmKpXj4a5AdmEHs0Bx4QMhf+iW15zY4Gg=
kubeops.dev/sidekick v0.0.12 h1:pmUjQLZDKxgREiM6z0PogLR1aDbgvkE9jRjbxG6dEt0=
kubeops.dev/sidekick v0.0.12/go.mod h1:RU7QH3E8DOLw15rBYlOOJSyczuwAnVVtYyZjJb00UB8=
kubestash.dev/apimachinery v0.27.0 h1:cBPAQRmXFlI/Z0A4IOCQ1r5fQcsV2/iLV8UrGTg7weQ=
kubestash.dev/apimachinery v0.27.0/go.mod h1:f3xtr2V2PWmpktitX4CQgE1g8Y49fyFbO8/FLpk/lJ4=
kubestash.dev/apimachinery v0.28.0-rc.0 h1:/8obzAxKhWzX4ar9Qyobqp7GFfVKKS1HnJD9q0orXZQ=
kubestash.dev/apimachinery v0.28.0-rc.0/go.mod h1:f3xtr2V2PWmpktitX4CQgE1g8Y49fyFbO8/FLpk/lJ4=
open-cluster-management.io/api v1.2.0 h1:+yeQgJiErrur5S4s205UM37EcZ2XbC9pFSm0xgV5/hU=
open-cluster-management.io/api v1.2.0/go.mod h1:YcmA6SpGEekIMxdoeVIIyOaBhMA6ImWRLXP4g8n8T+4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ func (b *BackupStorage) IsCredentialLessModeEnabled() bool {
switch b.Spec.Storage.Provider {
case ProviderS3:
return b.Spec.Storage.S3.SecretName == ""
// case ProviderGCS:
// case ProviderAzure:
case ProviderAzure:
return b.Spec.Storage.Azure.SecretName == ""
default:
return false
}
Expand Down
58 changes: 55 additions & 3 deletions vendor/kubestash.dev/apimachinery/pkg/cloud/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
kmapi "kmodules.xyz/client-go/api/v1"
kmc "kmodules.xyz/client-go/client"
"kmodules.xyz/client-go/meta"
sidekickapi "kubeops.dev/sidekick/apis/apps/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -52,6 +53,9 @@ const (
AzureSubscriptionIDAnnotation = "klusters.dev/azure-subscription-id"
AzureMIClientIDAnnotation = "azure.workload.identity/client-id"
AzureMITenantIDAnnotation = "azure.workload.identity/tenant-id"

AzureWorkloadIdentityUseLabel = "azure.workload.identity/use"
AzureWorkloadIdentityUseAnnotation = "azure.workload.identity/use-identity-binding"
)

func GetCloudAnnotations(ctx context.Context, kc client.Client, storages ...storageapi.BackupStorage) (map[string]string, error) {
Expand Down Expand Up @@ -139,12 +143,20 @@ func setBucketAnnotations(annotations map[string]string, storages ...storageapi.
}

func AddCloudAnnotationsToSAIfNeeded(ctx context.Context, kbClient client.Client,
bs *storageapi.BackupStorage, saRef *kmapi.ObjectReference, invTypRef *core.TypedObjectReference,
bs *storageapi.BackupStorage, sidekick *sidekickapi.Sidekick, invTypRef *core.TypedObjectReference,
) (bool, error) {
sa, err := getServiceAccount(ctx, kbClient, saRef)
sa, err := getServiceAccount(ctx, kbClient, &kmapi.ObjectReference{
Name: sidekick.Spec.ServiceAccountName,
Namespace: sidekick.Namespace,
})
if err != nil {
return true, fmt.Errorf("failed to get service account: %v", err)
}

if bs.IsCredentialLessModeEnabled() {
addSidekickAnnotationsIfNeeded(sidekick, bs)
}

if !isCloudAnnotationNeeded(bs, sa) { // Return if not needed
return false, nil
}
Expand All @@ -168,11 +180,28 @@ func AddCloudAnnotationsToSAIfNeeded(ctx context.Context, kbClient client.Client
return false, nil
}

func addSidekickAnnotationsIfNeeded(sidekick *sidekickapi.Sidekick, bs *storageapi.BackupStorage) {
if bs.Spec.Storage.Provider == storageapi.ProviderAzure {
if sidekick.Labels == nil {
sidekick.Labels = make(map[string]string)
}
sidekick.Labels[AzureWorkloadIdentityUseLabel] = "true"
if sidekick.Annotations == nil {
sidekick.Annotations = make(map[string]string)
}
sidekick.Annotations[AzureWorkloadIdentityUseAnnotation] = "true"
}
}

func hasCredLessManagerProvidedAnnotation(bs *storageapi.BackupStorage, sa *core.ServiceAccount) bool {
switch bs.Spec.Storage.Provider {
case storageapi.ProviderS3:
_, exists := sa.Annotations[AWSIRSARoleAnnotation]
return exists
case storageapi.ProviderAzure:
_, hasClientId := sa.Annotations[AzureMIClientIDAnnotation]
_, hasTenantId := sa.Annotations[AzureMITenantIDAnnotation]
return hasClientId && hasTenantId
default:
return false
}
Expand All @@ -184,7 +213,10 @@ func isCloudAnnotationNeeded(bs *storageapi.BackupStorage, sa *core.ServiceAccou
case storageapi.ProviderS3:
_, ok := sa.Annotations[AWSSeedRoleAnnotationName]
return !ok
// case storageapi.ProviderAzure:
case storageapi.ProviderAzure:
_, hasClientId := sa.Annotations[AzureMIClientIDAnnotation]
_, hasTenantId := sa.Annotations[AzureMITenantIDAnnotation]
return !hasTenantId || !hasClientId
}
}
return false
Expand Down Expand Up @@ -260,6 +292,10 @@ func hasRequiredCloudAnnotations(bs *storageapi.BackupStorage, sa *core.ServiceA
if bs.Spec.Storage.Provider == storageapi.ProviderS3 {
return sa.Annotations[AWSSeedRoleAnnotationName] != "" && sa.Annotations[BucketAnnotationKey] != ""
}
if bs.Spec.Storage.Provider == storageapi.ProviderAzure {
return sa.Annotations[AzureSubscriptionIDAnnotation] != "" && sa.Annotations[AzureMINameAnnotation] != "" &&
sa.Annotations[AzureResourceGroupAnnotation] != ""
}
return false
}

Expand Down Expand Up @@ -431,12 +467,28 @@ func getAWSAnnotations(source map[string]string) (map[string]string, error) {
return annotations, nil
}

func getAzureAnnotations(source map[string]string) (map[string]string, error) {
required := map[string]string{
AzureSubscriptionIDAnnotation: source[AzureSubscriptionIDAnnotation],
AzureMINameAnnotation: source[AzureMINameAnnotation],
AzureResourceGroupAnnotation: source[AzureResourceGroupAnnotation],
BucketAnnotationKey: source[BucketAnnotationKey],
}
annotations := make(map[string]string)
for key, val := range required {
annotations[key] = val
}
return annotations, nil
}

func getRequiredAnnotations(bs *storageapi.BackupStorage, annotations map[string]string) (map[string]string, error) {
switch bs.Spec.Storage.Provider {
case storageapi.ProviderS3:
return getAWSAnnotations(annotations)
// case storageapi.ProviderGCS:
// return applyGCPAnnotations(sa, annotations)
case storageapi.ProviderAzure:
return getAzureAnnotations(annotations)
default:
return nil, fmt.Errorf("unsupported storage provider: %s", bs.Spec.Storage.Provider)

Expand Down
2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1883,7 +1883,7 @@ kubeops.dev/petset/crds
kubeops.dev/sidekick/apis/apps
kubeops.dev/sidekick/apis/apps/v1alpha1
kubeops.dev/sidekick/crds
# kubestash.dev/apimachinery v0.27.0
# kubestash.dev/apimachinery v0.28.0-rc.0
## explicit; go 1.25.0
kubestash.dev/apimachinery/apis
kubestash.dev/apimachinery/apis/addons/v1alpha1
Expand Down
Loading