Skip to content

ossfs2: support secretref in runc #1367

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
38 changes: 38 additions & 0 deletions pkg/mounter/oss/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"fmt"
"os"

"github.com/alibabacloud-go/tea/tea"
"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/cloud/metadata"
"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/features"
"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/utils"
mounterutils "github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/utils"
corev1 "k8s.io/api/core/v1"
"k8s.io/klog/v2"
)

Expand All @@ -18,6 +20,14 @@ const (
OssFs2Type = "ossfs2"
)

// keys for STS token
const (
KeyAccessKeyId = "AccessKeyId"
KeyAccessKeySecret = "AccessKeySecret"
KeyExpiration = "Expiration"
KeySecurityToken = "SecurityToken"
)

func setDefaultImage(fuseType string, m metadata.MetadataProvider, config *mounterutils.FuseContainerConfig) {
if config.Image == "" {
registry, _ := m.Get(metadata.RegistryURL)
Expand Down Expand Up @@ -115,3 +125,31 @@ func getSTSEndpoint(region string) string {
}
return fmt.Sprintf("https://sts-vpc.%s.aliyuncs.com", region)
}

// keep consistent with RAM response
var secretRefKeysToParse []string = []string{
KeyAccessKeyId,
KeyAccessKeySecret,
KeyExpiration, // only used in ossfs1.0
KeySecurityToken,
}

func getPasswdSecretVolume(secretRef, fuseType string) (secret *corev1.SecretVolumeSource) {
if secretRef == "" {
return nil
}
items := []corev1.KeyToPath{}
for _, key := range secretRefKeysToParse {
item := corev1.KeyToPath{
Key: key,
Path: fmt.Sprintf("%s/%s", utils.GetPasswdFileName(fuseType), key),
Mode: tea.Int32(0600),
}
items = append(items, item)
}
secret = &corev1.SecretVolumeSource{
SecretName: secretRef,
Items: items,
}
return
}
58 changes: 58 additions & 0 deletions pkg/mounter/oss/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"reflect"
"testing"

"github.com/alibabacloud-go/tea/tea"
"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/cloud/metadata"
"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/utils"
mounterutils "github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/utils"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
"k8s.io/component-base/featuregate"
)

Expand Down Expand Up @@ -195,3 +197,59 @@ func Test_getSTSEndpoint(t *testing.T) {
})
}
}

func Test_getPasswdSecretVolume(t *testing.T) {
tests := []struct {
name string
secretRef string
expectedEmpty bool
expectedName string
expectedItems []corev1.KeyToPath
}{
{
name: "TestEmptySecretRef",
secretRef: "",
expectedEmpty: true,
},
{
name: "TestNonEmptySecretRef",
secretRef: "my-secret",
expectedEmpty: false,
expectedName: "my-secret",
expectedItems: []corev1.KeyToPath{
{
Key: "AccessKeyId",
Path: "passwd-ossfs/AccessKeyId",
Mode: tea.Int32(0600),
},
{
Key: "AccessKeySecret",
Path: "passwd-ossfs/AccessKeySecret",
Mode: tea.Int32(0600),
},
{
Key: "Expiration",
Path: "passwd-ossfs/Expiration",
Mode: tea.Int32(0600),
},
{
Key: "SecurityToken",
Path: "passwd-ossfs/SecurityToken",
Mode: tea.Int32(0600),
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
secret := getPasswdSecretVolume(tt.secretRef, "ossfs")

assert.Equal(t, tt.expectedEmpty, secret == nil)
if secret != nil {
assert.Equal(t, tt.expectedName, secret.SecretName)
assert.Equal(t, tt.expectedItems, secret.Items)
}
})
}
}
41 changes: 6 additions & 35 deletions pkg/mounter/oss/ossfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func (f *fuseOssfs) buildPodSpec(c *utils.FusePodContext, target string) (spec c
},
}

buildOssfsAuthSpec(c, target, &spec, &container)
f.buildAuthSpec(c, target, &spec, &container)

container.Args = []string{"--socket=" + socketPath, "-v=4"}

Expand Down Expand Up @@ -265,14 +265,14 @@ func (f *fuseOssfs) MakeMountOptions(o *Options, m metadata.MetadataProvider) (m
mountOptions = append(mountOptions, fmt.Sprintf("region=%s", region))
}

authOptions := o.getAuthOptions(region)
authOptions := f.getAuthOptions(o, region)
mountOptions = append(mountOptions, authOptions...)

return mountOptions, nil

}

func (o *Options) getAuthOptions(region string) (mountOptions []string) {
func (f *fuseOssfs) getAuthOptions(o *Options, region string) (mountOptions []string) {
switch o.AuthType {
case AuthTypePublic:
mountOptions = append(mountOptions, "public_bucket=1")
Expand Down Expand Up @@ -332,7 +332,7 @@ func (f *fuseOssfs) AddDefaultMountOptions(options []string) []string {
return options
}

func buildOssfsAuthSpec(c *utils.FusePodContext, target string, spec *corev1.PodSpec, container *corev1.Container) {
func (f *fuseOssfs) buildAuthSpec(c *utils.FusePodContext, target string, spec *corev1.PodSpec, container *corev1.Container) {
if spec == nil || container == nil {
return
}
Expand Down Expand Up @@ -411,10 +411,10 @@ func buildOssfsAuthSpec(c *utils.FusePodContext, target string, spec *corev1.Pod
}
container.VolumeMounts = append(container.VolumeMounts, secretStoreVolumeMount)
default:
secretVolumeSource := getPasswdSecretVolume(authCfg.SecretRef)
secretVolumeSource := getPasswdSecretVolume(authCfg.SecretRef, c.FuseType)
if secretVolumeSource != nil {
passwdSecretVolume := corev1.Volume{
Name: "passwd-ossfs",
Name: utils.GetPasswdFileName(c.FuseType),
VolumeSource: corev1.VolumeSource{
Secret: secretVolumeSource,
},
Expand All @@ -428,32 +428,3 @@ func buildOssfsAuthSpec(c *utils.FusePodContext, target string, spec *corev1.Pod
}
}
}

// keep consistent with RAM response
var secretRefKeysToParse []string = []string{
"AccessKeyId",
"AccessKeySecret",
"Expiration",
"SecurityToken",
}

func getPasswdSecretVolume(secretRef string) (secret *corev1.SecretVolumeSource) {
passwdFilename := "passwd-ossfs"
if secretRef == "" {
return nil
}
items := []corev1.KeyToPath{}
for _, key := range secretRefKeysToParse {
item := corev1.KeyToPath{
Key: key,
Path: fmt.Sprintf("%s/%s", passwdFilename, key),
Mode: tea.Int32(0600),
}
items = append(items, item)
}
secret = &corev1.SecretVolumeSource{
SecretName: secretRef,
Items: items,
}
return
}
62 changes: 59 additions & 3 deletions pkg/mounter/oss/ossfs2.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ func (f *fuseOssfs2) PrecheckAuthConfig(o *Options, onNode bool) error {
if features.FunctionalMutableFeatureGate.Enabled(features.RundCSIProtocol3) {
return nil
}
if o.SecretRef != "" {
if o.AkID != "" || o.AkSecret != "" {
return fmt.Errorf("AK and secretRef cannot be set at the same time")
}
if o.SecretRef == utils.GetCredientialsSecretName(OssFsType) {
return fmt.Errorf("invalid SecretRef name")
}
return nil
}
// aksk may retrieve from ENV
if onNode && (o.AkID == "" || o.AkSecret == "") {
return fmt.Errorf("missing access key in node publish secret")
Expand All @@ -61,13 +70,17 @@ func (f *fuseOssfs2) PrecheckAuthConfig(o *Options, onNode bool) error {
return nil
}

func (f *fuseOssfs2) MakeAuthConfig(o *Options, m metadata.MetadataProvider) (*utils.AuthConfig, error) {
authCfg := &utils.AuthConfig{}
func (f *fuseOssfs2) MakeAuthConfig(o *Options, m metadata.MetadataProvider) (authCfg *utils.AuthConfig, err error) {
authCfg = &utils.AuthConfig{}
if o.SecretRef != "" {
authCfg.SecretRef = o.SecretRef
return
}
authCfg.Secrets = map[string]string{
utils.GetPasswdFileName(f.Name()): fmt.Sprintf("--oss_access_key_id=%s\n--oss_access_key_secret=%s", o.AkID, o.AkSecret),
}

return authCfg, nil
return
}

func (f *fuseOssfs2) MakeMountOptions(o *Options, m metadata.MetadataProvider) (mountOptions []string, err error) {
Expand All @@ -88,6 +101,10 @@ func (f *fuseOssfs2) MakeMountOptions(o *Options, m metadata.MetadataProvider) (
}
mountOptions = append(mountOptions, fmt.Sprintf("oss_region=%s", region))
}

authOptions := f.getAuthOptions(o)
mountOptions = append(mountOptions, authOptions...)

return
}

Expand All @@ -105,6 +122,17 @@ func (f *fuseOssfs2) PodTemplateSpec(c *utils.FusePodContext, target string) (*c
return pod, nil
}

func (f *fuseOssfs2) getAuthOptions(o *Options) (mountOptions []string) {
if o.SecretRef != "" {
mountOptions = append(mountOptions,
fmt.Sprintf("oss_sts_multi_conf_ak_file=%s", filepath.Join(utils.GetConfigDir(o.FuseType), utils.GetPasswdFileName(o.FuseType), KeyAccessKeyId)),
fmt.Sprintf("oss_sts_multi_conf_sk_file=%s", filepath.Join(utils.GetConfigDir(o.FuseType), utils.GetPasswdFileName(o.FuseType), KeyAccessKeySecret)),
fmt.Sprintf("oss_sts_multi_conf_token_file=%s", filepath.Join(utils.GetConfigDir(o.FuseType), utils.GetPasswdFileName(o.FuseType), KeySecurityToken)),
)
}
return
}

func (f *fuseOssfs2) buildPodSpec(c *utils.FusePodContext, target string) (spec corev1.PodSpec, _ error) {
targetDir := filepath.Dir(target)
targetDirVolume := corev1.Volume{
Expand Down Expand Up @@ -146,6 +174,8 @@ func (f *fuseOssfs2) buildPodSpec(c *utils.FusePodContext, target string) (spec
},
}

f.buildAuthSpec(c, &spec, &container)

container.Args = []string{"--socket=" + socketPath, "-v=4"}

spec.Containers = []corev1.Container{container}
Expand Down Expand Up @@ -183,3 +213,29 @@ func (f *fuseOssfs2) AddDefaultMountOptions(options []string) []string {

return options
}

func (f *fuseOssfs2) buildAuthSpec(c *utils.FusePodContext, spec *corev1.PodSpec, container *corev1.Container) {
if spec == nil || container == nil {
return
}
authCfg := c.AuthConfig
if authCfg == nil {
return
}

secretVolumeSource := getPasswdSecretVolume(authCfg.SecretRef, c.FuseType)
if secretVolumeSource != nil {
passwdSecretVolume := corev1.Volume{
Name: utils.GetPasswdFileName(c.FuseType),
VolumeSource: corev1.VolumeSource{
Secret: secretVolumeSource,
},
}
spec.Volumes = append(spec.Volumes, passwdSecretVolume)
passwdVolumeMont := corev1.VolumeMount{
Name: passwdSecretVolume.Name,
MountPath: utils.GetConfigDir(c.FuseType),
}
container.VolumeMounts = append(container.VolumeMounts, passwdVolumeMont)
}
}
Loading