Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

operator: adds AWS sts support #11481

Merged
merged 22 commits into from Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions operator/internal/handlers/internal/storage/secrets.go
Expand Up @@ -139,6 +139,7 @@ func extractS3ConfigSecret(s *corev1.Secret) (*storage.S3StorageConfig, error) {
roleArn := s.Data[storage.KeyAWSRoleArn]
// Optional fields
region := s.Data[storage.KeyAWSRegion]
audience := s.Data[storage.KeyAWSAudience]

if len(roleArn) == 0 {
if len(endpoint) == 0 {
Expand Down Expand Up @@ -166,6 +167,7 @@ func extractS3ConfigSecret(s *corev1.Secret) (*storage.S3StorageConfig, error) {
Endpoint: string(endpoint),
Buckets: string(buckets),
Region: string(region),
Audience: string(audience),
SSE: sseCfg,
}, nil
}
Expand Down
58 changes: 56 additions & 2 deletions operator/internal/manifests/storage/configure.go
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/imdario/mergo"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"

lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
)
Expand Down Expand Up @@ -106,7 +107,7 @@ func configureStatefulSetCA(s *appsv1.StatefulSet, tls *TLSConfig) error {
}

func ensureObjectStoreCredentials(p *corev1.PodSpec, opts Options) corev1.PodSpec {
var envVarFromSecret = func(name, secretName, secretKey string) corev1.EnvVar {
envVarFromSecret := func(name, secretName, secretKey string) corev1.EnvVar {
return corev1.EnvVar{
Name: name,
ValueFrom: &corev1.EnvVarSource{
Expand Down Expand Up @@ -139,6 +140,11 @@ func ensureObjectStoreCredentials(p *corev1.PodSpec, opts Options) corev1.PodSpe
MountPath: secretDirectory,
})

if wifEnabled(opts) {
volumes = append(volumes, saTokenVolume(opts))
container.VolumeMounts = append(container.VolumeMounts, saTokenVolumeMount(opts))
}

var storeEnvVars []corev1.EnvVar
switch storeType {
case lokiv1.ObjectStorageSecretAlibabaCloud:
Expand All @@ -164,7 +170,7 @@ func ensureObjectStoreCredentials(p *corev1.PodSpec, opts Options) corev1.PodSpe
envVarFromSecret(EnvAWSAccessKeySecret, secretName, KeyAWSAccessKeySecret),
}
// STS Auth Workflow
if opts.S3 != nil && opts.S3.RoleArn == "" {
if wifEnabled(opts) {
storeEnvVars = []corev1.EnvVar{
envVarFromSecret(EnvAWSRoleArn, secretName, KeyAWSRoleArn),
// TODO (JoaoBraveCoding) fix
Expand Down Expand Up @@ -223,3 +229,51 @@ func ensureCAForS3(p *corev1.PodSpec, tls *TLSConfig) corev1.PodSpec {
Volumes: volumes,
}
}

func wifEnabled(opts Options) bool {
storeType := opts.SharedStore
switch storeType {
case lokiv1.ObjectStorageSecretS3:
return opts.S3 != nil && opts.S3.RoleArn == ""
default:
return false
}
}

func saTokenVolumeMount(opts Options) corev1.VolumeMount {
var wiToken string
storeType := opts.SharedStore
switch storeType {
case lokiv1.ObjectStorageSecretS3:
wiToken = opts.S3.WebIdentityTokenFile
}
return corev1.VolumeMount{
Name: saTokenVolumeName,
MountPath: wiToken,
}
}

func saTokenVolume(opts Options) corev1.Volume {
var audience string
storeType := opts.SharedStore
switch storeType {
case lokiv1.ObjectStorageSecretS3:
audience = opts.S3.Audience
}
JoaoBraveCoding marked this conversation as resolved.
Show resolved Hide resolved
return corev1.Volume{
Name: saTokenVolumeName,
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{
{
ServiceAccountToken: &corev1.ServiceAccountTokenProjection{
ExpirationSeconds: pointer.Int64(saTokenExpiration),
Path: corev1.ServiceAccountTokenKey,
Audience: audience,
},
},
},
},
},
}
}
1 change: 1 addition & 0 deletions operator/internal/manifests/storage/options.go
Expand Up @@ -40,6 +40,7 @@ type S3StorageConfig struct {
Buckets string
RoleArn string
WebIdentityTokenFile string
Audience string
SSE S3SSEConfig
}

Expand Down
7 changes: 7 additions & 0 deletions operator/internal/manifests/storage/var.go
Expand Up @@ -53,6 +53,8 @@ const (
KeyAWSSseKmsKeyID = "sse_kms_key_id"
// KeyAWSRoleArn is the secret data key for the AWS STS role ARN.
KeyAWSRoleArn = "role_arn"
// KeyAWSAudience is the audience for the AWS STS workflow.
KeyAWSAudience = "audience"

// KeyAzureStorageAccountKey is the secret data key for the Azure storage account key.
KeyAzureStorageAccountKey = "account_key"
Expand Down Expand Up @@ -99,6 +101,11 @@ const (
// KeySwiftPassword is the secret data key for the OpenStack Swift password.
KeySwiftUsername = "username"

saTokenVolumeName = "bound-sa-token"
saTokenVolumeK8sDirectory = "/var/run/secrets/kubernetes/serviceaccount"
JoaoBraveCoding marked this conversation as resolved.
Show resolved Hide resolved
saTokenVolumeOcpDirectory = "/var/run/secrets/openshift/serviceaccount"
saTokenExpiration = 3600
periklis marked this conversation as resolved.
Show resolved Hide resolved

secretDirectory = "/etc/storage/secrets"
storageTLSVolume = "storage-tls"
caDirectory = "/etc/storage/ca"
Expand Down