k8s.io/kubernetes@v1.29.3/pkg/volume/azure_file/azure_util.go (about)

     1  //go:build !providerless
     2  // +build !providerless
     3  
     4  /*
     5  Copyright 2016 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package azure_file
    21  
    22  import (
    23  	"context"
    24  	"fmt"
    25  	"strings"
    26  
    27  	v1 "k8s.io/api/core/v1"
    28  	"k8s.io/apimachinery/pkg/api/errors"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"k8s.io/kubernetes/pkg/volume"
    31  )
    32  
    33  const (
    34  	fileMode        = "file_mode"
    35  	dirMode         = "dir_mode"
    36  	gid             = "gid"
    37  	vers            = "vers"
    38  	actimeo         = "actimeo"
    39  	mfsymlinks      = "mfsymlinks"
    40  	defaultFileMode = "0777"
    41  	defaultDirMode  = "0777"
    42  	defaultVers     = "3.0"
    43  	defaultActimeo  = "30"
    44  )
    45  
    46  // Abstract interface to azure file operations.
    47  type azureUtil interface {
    48  	GetAzureCredentials(host volume.VolumeHost, nameSpace, secretName string) (string, string, error)
    49  	SetAzureCredentials(host volume.VolumeHost, nameSpace, accountName, accountKey string) (string, error)
    50  }
    51  
    52  type azureSvc struct{}
    53  
    54  func (s *azureSvc) GetAzureCredentials(host volume.VolumeHost, nameSpace, secretName string) (string, string, error) {
    55  	var accountKey, accountName string
    56  	kubeClient := host.GetKubeClient()
    57  	if kubeClient == nil {
    58  		return "", "", fmt.Errorf("cannot get kube client")
    59  	}
    60  
    61  	keys, err := kubeClient.CoreV1().Secrets(nameSpace).Get(context.TODO(), secretName, metav1.GetOptions{})
    62  	if err != nil {
    63  		return "", "", fmt.Errorf("couldn't get secret %v/%v", nameSpace, secretName)
    64  	}
    65  	for name, data := range keys.Data {
    66  		if name == "azurestorageaccountname" {
    67  			accountName = string(data)
    68  		}
    69  		if name == "azurestorageaccountkey" {
    70  			accountKey = string(data)
    71  		}
    72  	}
    73  	if accountName == "" || accountKey == "" {
    74  		return "", "", fmt.Errorf("invalid %v/%v, couldn't extract azurestorageaccountname or azurestorageaccountkey", nameSpace, secretName)
    75  	}
    76  	accountName = strings.TrimSpace(accountName)
    77  	return accountName, accountKey, nil
    78  }
    79  
    80  func (s *azureSvc) SetAzureCredentials(host volume.VolumeHost, nameSpace, accountName, accountKey string) (string, error) {
    81  	kubeClient := host.GetKubeClient()
    82  	if kubeClient == nil {
    83  		return "", fmt.Errorf("cannot get kube client")
    84  	}
    85  	secretName := "azure-storage-account-" + accountName + "-secret"
    86  	secret := &v1.Secret{
    87  		ObjectMeta: metav1.ObjectMeta{
    88  			Namespace: nameSpace,
    89  			Name:      secretName,
    90  		},
    91  		Data: map[string][]byte{
    92  			"azurestorageaccountname": []byte(accountName),
    93  			"azurestorageaccountkey":  []byte(accountKey),
    94  		},
    95  		Type: "Opaque",
    96  	}
    97  	_, err := kubeClient.CoreV1().Secrets(nameSpace).Create(context.TODO(), secret, metav1.CreateOptions{})
    98  	if errors.IsAlreadyExists(err) {
    99  		err = nil
   100  	}
   101  	if err != nil {
   102  		return "", fmt.Errorf("couldn't create secret %v", err)
   103  	}
   104  	return secretName, err
   105  }
   106  
   107  // check whether mountOptions contain file_mode, dir_mode, vers, gid, if not, append default mode
   108  func appendDefaultMountOptions(mountOptions []string, fsGroup *int64) []string {
   109  	fileModeFlag := false
   110  	dirModeFlag := false
   111  	versFlag := false
   112  	gidFlag := false
   113  	actimeoFlag := false
   114  	mfsymlinksFlag := false
   115  
   116  	for _, mountOption := range mountOptions {
   117  		if strings.HasPrefix(mountOption, fileMode) {
   118  			fileModeFlag = true
   119  		}
   120  		if strings.HasPrefix(mountOption, dirMode) {
   121  			dirModeFlag = true
   122  		}
   123  		if strings.HasPrefix(mountOption, vers) {
   124  			versFlag = true
   125  		}
   126  		if strings.HasPrefix(mountOption, gid) {
   127  			gidFlag = true
   128  		}
   129  		if strings.HasPrefix(mountOption, actimeo) {
   130  			actimeoFlag = true
   131  		}
   132  		if strings.HasPrefix(mountOption, mfsymlinks) {
   133  			mfsymlinksFlag = true
   134  		}
   135  	}
   136  
   137  	allMountOptions := mountOptions
   138  	if !fileModeFlag {
   139  		allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", fileMode, defaultFileMode))
   140  	}
   141  
   142  	if !dirModeFlag {
   143  		allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", dirMode, defaultDirMode))
   144  	}
   145  
   146  	if !versFlag {
   147  		allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", vers, defaultVers))
   148  	}
   149  
   150  	if !gidFlag && fsGroup != nil {
   151  		allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%d", gid, *fsGroup))
   152  	}
   153  
   154  	if !actimeoFlag {
   155  		allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%s", actimeo, defaultActimeo))
   156  	}
   157  
   158  	if !mfsymlinksFlag {
   159  		allMountOptions = append(allMountOptions, mfsymlinks)
   160  	}
   161  	return allMountOptions
   162  }