in component/azstorage/config.go [303:543]
func ParseAndValidateConfig(az *AzStorage, opt AzStorageOptions) error {
log.Trace("ParseAndValidateConfig : Parsing config")
// Validate account name is present or not
if opt.AccountName == "" {
return errors.New("account name not provided")
}
az.stConfig.authConfig.AccountName = opt.AccountName
// Validate account type property
if opt.AccountType == "" {
opt.AccountType = "block"
}
if config.IsSet(compName + ".use-adls") {
if opt.UseAdls {
az.stConfig.authConfig.AccountType = az.stConfig.authConfig.AccountType.ADLS()
} else {
az.stConfig.authConfig.AccountType = az.stConfig.authConfig.AccountType.BLOCK()
}
} else {
var accountType AccountType
err := accountType.Parse(opt.AccountType)
if err != nil {
log.Err("ParseAndValidateConfig : Failed to parse account type %s", opt.AccountType)
return errors.New("invalid account type")
}
if accountType == EAccountType.INVALID_ACC() {
log.Err("ParseAndValidateConfig : Invalid account type %s", opt.AccountType)
return errors.New("invalid account type")
}
az.stConfig.authConfig.AccountType = accountType
}
if opt.BlockSize != 0 {
if opt.BlockSize > blockblob.MaxStageBlockBytes {
log.Err("ParseAndValidateConfig : Block size is too large. Block size has to be smaller than %s Bytes", blockblob.MaxStageBlockBytes)
return errors.New("block size is too large")
}
az.stConfig.blockSize = opt.BlockSize * 1024 * 1024
}
// Validate container name is present or not
err := config.UnmarshalKey("mount-all-containers", &az.stConfig.mountAllContainers)
if err != nil {
log.Err("ParseAndValidateConfig : Failed to detect mount-all-container")
}
if !az.stConfig.mountAllContainers && opt.Container == "" {
return errors.New("container name not provided")
}
az.stConfig.container = opt.Container
if config.IsSet(compName + ".use-https") {
opt.UseHTTP = !opt.UseHTTPS
}
if opt.CPKEnabled {
if opt.CPKEncryptionKey == "" || opt.CPKEncryptionKeySha256 == "" {
log.Err("ParseAndValidateConfig : CPK key or CPK key sha256 not provided")
return errors.New("CPK key or key sha256 not provided")
}
az.stConfig.cpkEnabled = opt.CPKEnabled
az.stConfig.cpkEncryptionKey = opt.CPKEncryptionKey
az.stConfig.cpkEncryptionKeySha256 = opt.CPKEncryptionKeySha256
}
// Validate endpoint
if opt.Endpoint == "" {
log.Warn("ParseAndValidateConfig : account endpoint not provided, assuming the default .core.windows.net style endpoint")
if az.stConfig.authConfig.AccountType == EAccountType.BLOCK() {
opt.Endpoint = fmt.Sprintf("%s.blob.core.windows.net", opt.AccountName)
} else if az.stConfig.authConfig.AccountType == EAccountType.ADLS() {
opt.Endpoint = fmt.Sprintf("%s.dfs.core.windows.net", opt.AccountName)
}
}
az.stConfig.authConfig.Endpoint = opt.Endpoint
az.stConfig.authConfig.Endpoint = formatEndpointProtocol(az.stConfig.authConfig.Endpoint, opt.UseHTTP)
az.stConfig.authConfig.Endpoint = formatEndpointAccountType(az.stConfig.authConfig.Endpoint, az.stConfig.authConfig.AccountType)
az.stConfig.authConfig.ActiveDirectoryEndpoint = opt.ActiveDirectoryEndpoint
az.stConfig.authConfig.ActiveDirectoryEndpoint = formatEndpointProtocol(az.stConfig.authConfig.ActiveDirectoryEndpoint, false)
// If subdirectory is mounted, take the prefix path
az.stConfig.prefixPath = removeLeadingSlashes(opt.PrefixPath)
// Block list call on mount for given amount of time
az.stConfig.cancelListForSeconds = opt.CancelListForSeconds
az.stConfig.telemetry = opt.Telemetry
httpProxyProvided := opt.HttpProxyAddress != ""
httpsProxyProvided := opt.HttpsProxyAddress != ""
// Set whether to use http or https and proxy
if opt.UseHTTP {
az.stConfig.authConfig.UseHTTP = true
if httpProxyProvided {
az.stConfig.proxyAddress = opt.HttpProxyAddress
} else if httpsProxyProvided {
az.stConfig.proxyAddress = opt.HttpsProxyAddress
}
} else {
if httpsProxyProvided {
az.stConfig.proxyAddress = opt.HttpsProxyAddress
} else {
if httpProxyProvided {
log.Err("ParseAndValidateConfig : `http-proxy` Invalid : must set `use-http: true` in your config file")
return errors.New("`http-proxy` Invalid : must set `use-http: true` in your config file")
}
}
}
az.stConfig.proxyAddress = formatEndpointProtocol(az.stConfig.proxyAddress, opt.UseHTTP)
log.Info("ParseAndValidateConfig : using the following proxy address from the config file: %s", az.stConfig.proxyAddress)
err = ParseAndReadDynamicConfig(az, opt, false)
if err != nil {
return err
}
log.Debug("ParseAndValidateConfig : Getting auth type")
if opt.AuthMode == "" {
// Based on other config decide the auth mode
// for e.g. if sas token is set then mode shall be set to sas and if key is set then authmode shall be key
opt.AuthMode = autoDetectAuthMode(opt)
log.Debug("ParseAndValidateConfig : Auth type %s", opt.AuthMode)
}
var authType AuthType
err = authType.Parse(opt.AuthMode)
if err != nil {
log.Err("ParseAndValidateConfig : Invalid auth type %s", opt.AccountType)
return errors.New("invalid auth type")
}
az.stConfig.authConfig.ObjectID = opt.ObjectID
switch authType {
case EAuthType.KEY():
az.stConfig.authConfig.AuthMode = EAuthType.KEY()
if opt.AccountKey == "" {
return errors.New("storage key not provided")
}
az.stConfig.authConfig.AccountKey = opt.AccountKey
case EAuthType.SAS():
az.stConfig.authConfig.AuthMode = EAuthType.SAS()
if opt.SaSKey == "" {
return errors.New("SAS key not provided")
}
az.stConfig.authConfig.SASKey = sanitizeSASKey(opt.SaSKey)
case EAuthType.MSI():
az.stConfig.authConfig.AuthMode = EAuthType.MSI()
err := validateMsiConfig(opt)
if err != nil {
return err
}
az.stConfig.authConfig.ApplicationID = opt.ApplicationID
az.stConfig.authConfig.ResourceID = opt.ResourceID
case EAuthType.SPN():
az.stConfig.authConfig.AuthMode = EAuthType.SPN()
if opt.ClientID == "" || (opt.ClientSecret == "" && opt.OAuthTokenFilePath == "" && opt.WorkloadIdentityToken == "") || opt.TenantID == "" {
//lint:ignore ST1005 ignore
return errors.New("Client ID, Tenant ID or Client Secret, OAuthTokenFilePath, WorkloadIdentityToken not provided")
}
az.stConfig.authConfig.ClientID = opt.ClientID
az.stConfig.authConfig.ClientSecret = opt.ClientSecret
az.stConfig.authConfig.TenantID = opt.TenantID
az.stConfig.authConfig.OAuthTokenFilePath = opt.OAuthTokenFilePath
az.stConfig.authConfig.WorkloadIdentityToken = opt.WorkloadIdentityToken
case EAuthType.AZCLI():
az.stConfig.authConfig.AuthMode = EAuthType.AZCLI()
case EAuthType.WORKLOADIDENTITY():
az.stConfig.authConfig.AuthMode = EAuthType.WORKLOADIDENTITY()
if opt.ClientID == "" || opt.TenantID == "" || opt.ApplicationID == "" {
return errors.New("Client ID, Tenant ID or Application ID not provided")
}
az.stConfig.authConfig.ClientID = opt.ClientID
az.stConfig.authConfig.TenantID = opt.TenantID
az.stConfig.authConfig.ApplicationID = opt.ApplicationID
az.stConfig.authConfig.UserAssertion = opt.UserAssertion
default:
log.Err("ParseAndValidateConfig : Invalid auth mode %s", opt.AuthMode)
return errors.New("invalid auth mode")
}
az.stConfig.authConfig.AuthResource = opt.AuthResourceString
// Retry policy configuration
// A user provided value of 0 doesn't make sense for MaxRetries, MaxTimeout, BackoffTime, or MaxRetryDelay.
az.stConfig.maxRetries = 5 // Max number of retry to be done (default 4) (v1 : 0)
az.stConfig.maxTimeout = 900 // Max timeout for any single retry (default 1 min) (v1 : 60)
az.stConfig.backoffTime = 4 // Delay before any retry (exponential increase) (default 4 sec)
az.stConfig.maxRetryDelay = 60 // Maximum allowed delay before retry (default 120 sec) (v1 : 1.2)
if opt.MaxRetries != 0 {
az.stConfig.maxRetries = opt.MaxRetries
}
if opt.MaxTimeout != 0 {
az.stConfig.maxTimeout = opt.MaxTimeout
}
if opt.BackoffTime != 0 {
az.stConfig.backoffTime = opt.BackoffTime
}
if opt.MaxRetryDelay != 0 {
az.stConfig.maxRetryDelay = opt.MaxRetryDelay
}
if config.IsSet(compName + ".set-content-type") {
log.Warn("unsupported v1 CLI parameter: set-content-type is always true in blobfuse2.")
}
if config.IsSet(compName + ".ca-cert-file") {
log.Warn("unsupported v1 CLI parameter: ca-cert-file is not supported in blobfuse2. Use the default ca cert path for your environment.")
}
if config.IsSet(compName + ".debug-libcurl") {
log.Warn("unsupported v1 CLI parameter: debug-libcurl is not applicable in blobfuse2.")
}
az.stConfig.preserveACL = opt.PreserveACL
if opt.Filter != "" {
err = configureBlobFilter(az, opt)
if err != nil {
return err
}
}
log.Crit("ParseAndValidateConfig : account %s, container %s, account-type %s, auth %s, prefix %s, endpoint %s, MD5 %v %v, virtual-directory %v, disable-compression %v, CPK %v",
az.stConfig.authConfig.AccountName, az.stConfig.container, az.stConfig.authConfig.AccountType, az.stConfig.authConfig.AuthMode,
az.stConfig.prefixPath, az.stConfig.authConfig.Endpoint, az.stConfig.validateMD5, az.stConfig.updateMD5, az.stConfig.virtualDirectory, az.stConfig.disableCompression, az.stConfig.cpkEnabled)
log.Crit("ParseAndValidateConfig : use-HTTP %t, block-size %d, max-concurrency %d, default-tier %s, fail-unsupported-op %t, mount-all-containers %t", az.stConfig.authConfig.UseHTTP, az.stConfig.blockSize, az.stConfig.maxConcurrency, az.stConfig.defaultTier, az.stConfig.ignoreAccessModifiers, az.stConfig.mountAllContainers)
log.Crit("ParseAndValidateConfig : Retry Config: retry-count %d, max-timeout %d, backoff-time %d, max-delay %d, preserve-acl: %v",
az.stConfig.maxRetries, az.stConfig.maxTimeout, az.stConfig.backoffTime, az.stConfig.maxRetryDelay, az.stConfig.preserveACL)
log.Crit("ParseAndValidateConfig : Telemetry : %s, honour-ACL %v", az.stConfig.telemetry, az.stConfig.honourACL)
return nil
}