mirror of
https://github.com/minio/minio.git
synced 2025-04-22 19:35:47 -04:00
handle racy updates to globalSite config (#19750)
``` ================== WARNING: DATA RACE Read at 0x0000082be990 by goroutine 205: github.com/minio/minio/cmd.setCommonHeaders() Previous write at 0x0000082be990 by main goroutine: github.com/minio/minio/cmd.lookupConfigs() ```
This commit is contained in:
parent
aa3fde1784
commit
08d74819b6
@ -783,7 +783,7 @@ func (a adminAPIHandlers) ImportBucketMetadataHandler(w http.ResponseWriter, r *
|
|||||||
}
|
}
|
||||||
switch fileName {
|
switch fileName {
|
||||||
case bucketNotificationConfig:
|
case bucketNotificationConfig:
|
||||||
config, err := event.ParseConfig(io.LimitReader(reader, sz), globalSite.Region, globalEventNotifier.targetList)
|
config, err := event.ParseConfig(io.LimitReader(reader, sz), globalSite.Region(), globalEventNotifier.targetList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpt.SetStatus(bucket, fileName, fmt.Errorf("%s (%s)", errorCodes[ErrMalformedXML].Description, err))
|
rpt.SetStatus(bucket, fileName, fmt.Errorf("%s (%s)", errorCodes[ErrMalformedXML].Description, err))
|
||||||
continue
|
continue
|
||||||
|
@ -2416,7 +2416,7 @@ func getServerInfo(ctx context.Context, pools, metrics bool, r *http.Request) ma
|
|||||||
return madmin.InfoMessage{
|
return madmin.InfoMessage{
|
||||||
Mode: string(mode),
|
Mode: string(mode),
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
Region: globalSite.Region,
|
Region: globalSite.Region(),
|
||||||
SQSARN: globalEventNotifier.GetARNList(false),
|
SQSARN: globalEventNotifier.GetARNList(false),
|
||||||
DeploymentID: globalDeploymentID(),
|
DeploymentID: globalDeploymentID(),
|
||||||
Buckets: buckets,
|
Buckets: buckets,
|
||||||
|
@ -456,9 +456,9 @@ func (e errorCodeMap) ToAPIErrWithErr(errCode APIErrorCode, err error) APIError
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
apiErr.Description = fmt.Sprintf("%s (%s)", apiErr.Description, err)
|
apiErr.Description = fmt.Sprintf("%s (%s)", apiErr.Description, err)
|
||||||
}
|
}
|
||||||
if globalSite.Region != "" {
|
if region := globalSite.Region(); region != "" {
|
||||||
if errCode == ErrAuthorizationHeaderMalformed {
|
if errCode == ErrAuthorizationHeaderMalformed {
|
||||||
apiErr.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", globalSite.Region)
|
apiErr.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", region)
|
||||||
return apiErr
|
return apiErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2579,7 +2579,7 @@ func getAPIErrorResponse(ctx context.Context, err APIError, resource, requestID,
|
|||||||
BucketName: reqInfo.BucketName,
|
BucketName: reqInfo.BucketName,
|
||||||
Key: reqInfo.ObjectName,
|
Key: reqInfo.ObjectName,
|
||||||
Resource: resource,
|
Resource: resource,
|
||||||
Region: globalSite.Region,
|
Region: globalSite.Region(),
|
||||||
RequestID: requestID,
|
RequestID: requestID,
|
||||||
HostID: hostID,
|
HostID: hostID,
|
||||||
ActualObjectSize: err.ObjectSize,
|
ActualObjectSize: err.ObjectSize,
|
||||||
|
@ -54,7 +54,7 @@ func setCommonHeaders(w http.ResponseWriter) {
|
|||||||
|
|
||||||
// Set `x-amz-bucket-region` only if region is set on the server
|
// Set `x-amz-bucket-region` only if region is set on the server
|
||||||
// by default minio uses an empty region.
|
// by default minio uses an empty region.
|
||||||
if region := globalSite.Region; region != "" {
|
if region := globalSite.Region(); region != "" {
|
||||||
w.Header().Set(xhttp.AmzBucketRegion, region)
|
w.Header().Set(xhttp.AmzBucketRegion, region)
|
||||||
}
|
}
|
||||||
w.Header().Set(xhttp.AcceptRanges, "bytes")
|
w.Header().Set(xhttp.AcceptRanges, "bytes")
|
||||||
|
@ -954,9 +954,9 @@ func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError
|
|||||||
|
|
||||||
switch err.Code {
|
switch err.Code {
|
||||||
case "InvalidRegion":
|
case "InvalidRegion":
|
||||||
err.Description = fmt.Sprintf("Region does not match; expecting '%s'.", globalSite.Region)
|
err.Description = fmt.Sprintf("Region does not match; expecting '%s'.", globalSite.Region())
|
||||||
case "AuthorizationHeaderMalformed":
|
case "AuthorizationHeaderMalformed":
|
||||||
err.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", globalSite.Region)
|
err.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", globalSite.Region())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar check to http.checkWriteHeaderCode
|
// Similar check to http.checkWriteHeaderCode
|
||||||
|
@ -178,7 +178,7 @@ func validateAdminSignature(ctx context.Context, r *http.Request, region string)
|
|||||||
|
|
||||||
logger.GetReqInfo(ctx).Cred = cred
|
logger.GetReqInfo(ctx).Cred = cred
|
||||||
logger.GetReqInfo(ctx).Owner = owner
|
logger.GetReqInfo(ctx).Owner = owner
|
||||||
logger.GetReqInfo(ctx).Region = globalSite.Region
|
logger.GetReqInfo(ctx).Region = globalSite.Region()
|
||||||
|
|
||||||
return cred, owner, ErrNone
|
return cred, owner, ErrNone
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ func authenticateRequest(ctx context.Context, r *http.Request, action policy.Act
|
|||||||
}
|
}
|
||||||
cred, owner, s3Err = getReqAccessKeyV2(r)
|
cred, owner, s3Err = getReqAccessKeyV2(r)
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
switch action {
|
switch action {
|
||||||
case policy.GetBucketLocationAction, policy.ListAllMyBucketsAction:
|
case policy.GetBucketLocationAction, policy.ListAllMyBucketsAction:
|
||||||
region = ""
|
region = ""
|
||||||
@ -384,7 +384,7 @@ func authenticateRequest(ctx context.Context, r *http.Request, action policy.Act
|
|||||||
|
|
||||||
logger.GetReqInfo(ctx).Cred = cred
|
logger.GetReqInfo(ctx).Cred = cred
|
||||||
logger.GetReqInfo(ctx).Owner = owner
|
logger.GetReqInfo(ctx).Owner = owner
|
||||||
logger.GetReqInfo(ctx).Region = globalSite.Region
|
logger.GetReqInfo(ctx).Region = globalSite.Region()
|
||||||
|
|
||||||
// region is valid only for CreateBucketAction.
|
// region is valid only for CreateBucketAction.
|
||||||
var region string
|
var region string
|
||||||
@ -684,7 +684,7 @@ func validateSignature(atype authType, r *http.Request) (auth.Credentials, bool,
|
|||||||
}
|
}
|
||||||
cred, owner, s3Err = getReqAccessKeyV2(r)
|
cred, owner, s3Err = getReqAccessKeyV2(r)
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
if s3Err = isReqAuthenticated(GlobalContext, r, region, serviceS3); s3Err != ErrNone {
|
if s3Err = isReqAuthenticated(GlobalContext, r, region, serviceS3); s3Err != ErrNone {
|
||||||
return cred, owner, s3Err
|
return cred, owner, s3Err
|
||||||
}
|
}
|
||||||
@ -745,7 +745,7 @@ func isPutRetentionAllowed(bucketName, objectName string, retDays int, retDate t
|
|||||||
func isPutActionAllowed(ctx context.Context, atype authType, bucketName, objectName string, r *http.Request, action policy.Action) (s3Err APIErrorCode) {
|
func isPutActionAllowed(ctx context.Context, atype authType, bucketName, objectName string, r *http.Request, action policy.Action) (s3Err APIErrorCode) {
|
||||||
var cred auth.Credentials
|
var cred auth.Credentials
|
||||||
var owner bool
|
var owner bool
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
switch atype {
|
switch atype {
|
||||||
case authTypeUnknown:
|
case authTypeUnknown:
|
||||||
return ErrSignatureVersionNotSupported
|
return ErrSignatureVersionNotSupported
|
||||||
|
@ -403,7 +403,7 @@ func TestIsReqAuthenticated(t *testing.T) {
|
|||||||
|
|
||||||
// Validates all testcases.
|
// Validates all testcases.
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
s3Error := isReqAuthenticated(ctx, testCase.req, globalSite.Region, serviceS3)
|
s3Error := isReqAuthenticated(ctx, testCase.req, globalSite.Region(), serviceS3)
|
||||||
if s3Error != testCase.s3Error {
|
if s3Error != testCase.s3Error {
|
||||||
if _, err := io.ReadAll(testCase.req.Body); toAPIErrorCode(ctx, err) != testCase.s3Error {
|
if _, err := io.ReadAll(testCase.req.Body); toAPIErrorCode(ctx, err) != testCase.s3Error {
|
||||||
t.Fatalf("Test %d: Unexpected S3 error: want %d - got %d (got after reading request %s)", i, testCase.s3Error, s3Error, toAPIError(ctx, err).Code)
|
t.Fatalf("Test %d: Unexpected S3 error: want %d - got %d (got after reading request %s)", i, testCase.s3Error, s3Error, toAPIError(ctx, err).Code)
|
||||||
@ -443,7 +443,7 @@ func TestCheckAdminRequestAuthType(t *testing.T) {
|
|||||||
{Request: mustNewPresignedRequest(http.MethodGet, "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied},
|
{Request: mustNewPresignedRequest(http.MethodGet, "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied},
|
||||||
}
|
}
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
if _, s3Error := checkAdminRequestAuth(ctx, testCase.Request, policy.AllAdminActions, globalSite.Region); s3Error != testCase.ErrCode {
|
if _, s3Error := checkAdminRequestAuth(ctx, testCase.Request, policy.AllAdminActions, globalSite.Region()); s3Error != testCase.ErrCode {
|
||||||
t.Errorf("Test %d: Unexpected s3error returned wanted %d, got %d", i, testCase.ErrCode, s3Error)
|
t.Errorf("Test %d: Unexpected s3error returned wanted %d, got %d", i, testCase.ErrCode, s3Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
|
|||||||
// Generate response.
|
// Generate response.
|
||||||
encodedSuccessResponse := encodeResponse(LocationResponse{})
|
encodedSuccessResponse := encodeResponse(LocationResponse{})
|
||||||
// Get current region.
|
// Get current region.
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
if region != globalMinioDefaultRegion {
|
if region != globalMinioDefaultRegion {
|
||||||
encodedSuccessResponse = encodeResponse(LocationResponse{
|
encodedSuccessResponse = encodeResponse(LocationResponse{
|
||||||
Location: region,
|
Location: region,
|
||||||
|
@ -66,8 +66,9 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
|
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config.SetRegion(globalSite.Region)
|
region := globalSite.Region()
|
||||||
if err = config.Validate(globalSite.Region, globalEventNotifier.targetList); err != nil {
|
config.SetRegion(region)
|
||||||
|
if err = config.Validate(region, globalEventNotifier.targetList); err != nil {
|
||||||
arnErr, ok := err.(*event.ErrARNNotFound)
|
arnErr, ok := err.(*event.ErrARNNotFound)
|
||||||
if ok {
|
if ok {
|
||||||
for i, queue := range config.QueueList {
|
for i, queue := range config.QueueList {
|
||||||
@ -134,7 +135,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := event.ParseConfig(io.LimitReader(r.Body, r.ContentLength), globalSite.Region, globalEventNotifier.targetList)
|
config, err := event.ParseConfig(io.LimitReader(r.Body, r.ContentLength), globalSite.Region(), globalEventNotifier.targetList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiErr := errorCodes.ToAPIErr(ErrMalformedXML)
|
apiErr := errorCodes.ToAPIErr(ErrMalformedXML)
|
||||||
if event.IsEventError(err) {
|
if event.IsEventError(err) {
|
||||||
|
@ -176,7 +176,10 @@ func minioConfigToConsoleFeatures() {
|
|||||||
os.Setenv("CONSOLE_STS_DURATION", valueSession)
|
os.Setenv("CONSOLE_STS_DURATION", valueSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Setenv("CONSOLE_MINIO_REGION", globalSite.Region)
|
os.Setenv("CONSOLE_MINIO_SITE_NAME", globalSite.Name())
|
||||||
|
os.Setenv("CONSOLE_MINIO_SITE_REGION", globalSite.Region())
|
||||||
|
os.Setenv("CONSOLE_MINIO_REGION", globalSite.Region())
|
||||||
|
|
||||||
os.Setenv("CONSOLE_CERT_PASSWD", env.Get("MINIO_CERT_PASSWD", ""))
|
os.Setenv("CONSOLE_CERT_PASSWD", env.Get("MINIO_CERT_PASSWD", ""))
|
||||||
|
|
||||||
// This section sets Browser (console) stored config
|
// This section sets Browser (console) stored config
|
||||||
|
@ -362,7 +362,7 @@ func validateSubSysConfig(ctx context.Context, s config.Config, subSys string, o
|
|||||||
}
|
}
|
||||||
case config.IdentityOpenIDSubSys:
|
case config.IdentityOpenIDSubSys:
|
||||||
if _, err := openid.LookupConfig(s,
|
if _, err := openid.LookupConfig(s,
|
||||||
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region); err != nil {
|
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case config.IdentityLDAPSubSys:
|
case config.IdentityLDAPSubSys:
|
||||||
@ -383,7 +383,7 @@ func validateSubSysConfig(ctx context.Context, s config.Config, subSys string, o
|
|||||||
}
|
}
|
||||||
case config.IdentityPluginSubSys:
|
case config.IdentityPluginSubSys:
|
||||||
if _, err := idplugin.LookupConfig(s[config.IdentityPluginSubSys][config.Default],
|
if _, err := idplugin.LookupConfig(s[config.IdentityPluginSubSys][config.Default],
|
||||||
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region); err != nil {
|
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case config.SubnetSubSys:
|
case config.SubnetSubSys:
|
||||||
@ -530,10 +530,11 @@ func lookupConfigs(s config.Config, objAPI ObjectLayer) {
|
|||||||
// but not federation.
|
// but not federation.
|
||||||
globalBucketFederation = etcdCfg.PathPrefix == "" && etcdCfg.Enabled
|
globalBucketFederation = etcdCfg.PathPrefix == "" && etcdCfg.Enabled
|
||||||
|
|
||||||
globalSite, err = config.LookupSite(s[config.SiteSubSys][config.Default], s[config.RegionSubSys][config.Default])
|
siteCfg, err := config.LookupSite(s[config.SiteSubSys][config.Default], s[config.RegionSubSys][config.Default])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
configLogIf(ctx, fmt.Errorf("Invalid site configuration: %w", err))
|
configLogIf(ctx, fmt.Errorf("Invalid site configuration: %w", err))
|
||||||
}
|
}
|
||||||
|
globalSite.Update(siteCfg)
|
||||||
|
|
||||||
globalAutoEncryption = crypto.LookupAutoEncryption() // Enable auto-encryption if enabled
|
globalAutoEncryption = crypto.LookupAutoEncryption() // Enable auto-encryption if enabled
|
||||||
if globalAutoEncryption && GlobalKMS == nil {
|
if globalAutoEncryption && GlobalKMS == nil {
|
||||||
|
@ -39,8 +39,8 @@ func TestServerConfig(t *testing.T) {
|
|||||||
t.Fatalf("Init Test config failed")
|
t.Fatalf("Init Test config failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if globalSite.Region != globalMinioDefaultRegion {
|
if globalSite.Region() != globalMinioDefaultRegion {
|
||||||
t.Errorf("Expecting region `us-east-1` found %s", globalSite.Region)
|
t.Errorf("Expecting region `us-east-1` found %s", globalSite.Region())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new region and verify.
|
// Set new region and verify.
|
||||||
@ -52,8 +52,8 @@ func TestServerConfig(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if site.Region != "us-west-1" {
|
if site.Region() != "us-west-1" {
|
||||||
t.Errorf("Expecting region `us-west-1` found %s", globalSite.Region)
|
t.Errorf("Expecting region `us-west-1` found %s", globalSite.Region())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := saveServerConfig(context.Background(), objLayer, globalServerConfig); err != nil {
|
if err := saveServerConfig(context.Background(), objLayer, globalServerConfig); err != nil {
|
||||||
|
@ -54,7 +54,7 @@ func (evnot *EventNotifier) GetARNList(onlyActive bool) []string {
|
|||||||
if evnot == nil {
|
if evnot == nil {
|
||||||
return arns
|
return arns
|
||||||
}
|
}
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
for targetID, target := range evnot.targetList.TargetMap() {
|
for targetID, target := range evnot.targetList.TargetMap() {
|
||||||
// httpclient target is part of ListenNotification
|
// httpclient target is part of ListenNotification
|
||||||
// which doesn't need to be listed as part of the ARN list
|
// which doesn't need to be listed as part of the ARN list
|
||||||
@ -79,8 +79,9 @@ func (evnot *EventNotifier) set(bucket BucketInfo, meta BucketMetadata) {
|
|||||||
if config == nil {
|
if config == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config.SetRegion(globalSite.Region)
|
region := globalSite.Region()
|
||||||
if err := config.Validate(globalSite.Region, globalEventNotifier.targetList); err != nil {
|
config.SetRegion(region)
|
||||||
|
if err := config.Validate(region, globalEventNotifier.targetList); err != nil {
|
||||||
if _, ok := err.(*event.ErrARNNotFound); !ok {
|
if _, ok := err.(*event.ErrARNNotFound); !ok {
|
||||||
internalLogIf(GlobalContext, err)
|
internalLogIf(GlobalContext, err)
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ func (driver *ftpDriver) MakeDir(ctx *ftp.Context, objPath string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if prefix == "" {
|
if prefix == "" {
|
||||||
return clnt.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{Region: globalSite.Region})
|
return clnt.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{Region: globalSite.Region()})
|
||||||
}
|
}
|
||||||
|
|
||||||
dirPath := buildMinioDir(prefix)
|
dirPath := buildMinioDir(prefix)
|
||||||
|
@ -209,9 +209,8 @@ var (
|
|||||||
// This flag is set to 'true' when MINIO_UPDATE env is set to 'off'. Default is false.
|
// This flag is set to 'true' when MINIO_UPDATE env is set to 'off'. Default is false.
|
||||||
globalInplaceUpdateDisabled = false
|
globalInplaceUpdateDisabled = false
|
||||||
|
|
||||||
globalSite = config.Site{
|
// Captures site name and region
|
||||||
Region: globalMinioDefaultRegion,
|
globalSite config.Site
|
||||||
}
|
|
||||||
|
|
||||||
// MinIO local server address (in `host:port` format)
|
// MinIO local server address (in `host:port` format)
|
||||||
globalMinioAddr = ""
|
globalMinioAddr = ""
|
||||||
|
@ -57,7 +57,7 @@ func parseLocationConstraint(r *http.Request) (location string, s3Error APIError
|
|||||||
} // else for both err as nil or io.EOF
|
} // else for both err as nil or io.EOF
|
||||||
location = locationConstraint.Location
|
location = locationConstraint.Location
|
||||||
if location == "" {
|
if location == "" {
|
||||||
location = globalSite.Region
|
location = globalSite.Region()
|
||||||
}
|
}
|
||||||
if !isValidLocation(location) {
|
if !isValidLocation(location) {
|
||||||
return location, ErrInvalidRegion
|
return location, ErrInvalidRegion
|
||||||
@ -69,7 +69,8 @@ func parseLocationConstraint(r *http.Request) (location string, s3Error APIError
|
|||||||
// Validates input location is same as configured region
|
// Validates input location is same as configured region
|
||||||
// of MinIO server.
|
// of MinIO server.
|
||||||
func isValidLocation(location string) bool {
|
func isValidLocation(location string) bool {
|
||||||
return globalSite.Region == "" || globalSite.Region == location
|
region := globalSite.Region()
|
||||||
|
return region == "" || region == location
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supported headers that needs to be extracted.
|
// Supported headers that needs to be extracted.
|
||||||
@ -243,7 +244,7 @@ func extractReqParams(r *http.Request) map[string]string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
cred := getReqAccessCred(r, region)
|
cred := getReqAccessCred(r, region)
|
||||||
|
|
||||||
principalID := cred.AccessKey
|
principalID := cred.AccessKey
|
||||||
|
@ -230,7 +230,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer, etcdClient *etc
|
|||||||
globalServerConfigMu.RUnlock()
|
globalServerConfigMu.RUnlock()
|
||||||
|
|
||||||
openidConfig, err := openid.LookupConfig(s,
|
openidConfig, err := openid.LookupConfig(s,
|
||||||
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region)
|
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
iamLogIf(ctx, fmt.Errorf("Unable to initialize OpenID: %w", err), logger.WarningKind)
|
iamLogIf(ctx, fmt.Errorf("Unable to initialize OpenID: %w", err), logger.WarningKind)
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer, etcdClient *etc
|
|||||||
}
|
}
|
||||||
|
|
||||||
authNPluginCfg, err := idplugin.LookupConfig(s[config.IdentityPluginSubSys][config.Default],
|
authNPluginCfg, err := idplugin.LookupConfig(s[config.IdentityPluginSubSys][config.Default],
|
||||||
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region)
|
NewHTTPTransport(), xhttp.DrainBody, globalSite.Region())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
iamLogIf(ctx, fmt.Errorf("Unable to initialize AuthNPlugin: %w", err), logger.WarningKind)
|
iamLogIf(ctx, fmt.Errorf("Unable to initialize AuthNPlugin: %w", err), logger.WarningKind)
|
||||||
}
|
}
|
||||||
|
@ -1328,7 +1328,7 @@ func getRemoteInstanceTransport() http.RoundTripper {
|
|||||||
// Returns a minio-go Client configured to access remote host described by destDNSRecord
|
// Returns a minio-go Client configured to access remote host described by destDNSRecord
|
||||||
// Applicable only in a federated deployment
|
// Applicable only in a federated deployment
|
||||||
var getRemoteInstanceClient = func(r *http.Request, host string) (*miniogo.Core, error) {
|
var getRemoteInstanceClient = func(r *http.Request, host string) (*miniogo.Core, error) {
|
||||||
cred := getReqAccessCred(r, globalSite.Region)
|
cred := getReqAccessCred(r, globalSite.Region())
|
||||||
// In a federated deployment, all the instances share config files
|
// In a federated deployment, all the instances share config files
|
||||||
// and hence expected to have same credentials.
|
// and hence expected to have same credentials.
|
||||||
core, err := miniogo.NewCore(host, &miniogo.Options{
|
core, err := miniogo.NewCore(host, &miniogo.Options{
|
||||||
@ -2103,7 +2103,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
}
|
}
|
||||||
|
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Err = reqSignatureV4Verify(r, globalSite.Region, serviceS3); s3Err != ErrNone {
|
if s3Err = reqSignatureV4Verify(r, globalSite.Region(), serviceS3); s3Err != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2521,7 +2521,7 @@ func (api objectAPIHandlers) PutObjectExtractHandler(w http.ResponseWriter, r *h
|
|||||||
}
|
}
|
||||||
|
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Err = reqSignatureV4Verify(r, globalSite.Region, serviceS3); s3Err != ErrNone {
|
if s3Err = reqSignatureV4Verify(r, globalSite.Region(), serviceS3); s3Err != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ func getLambdaEventData(bucket, object string, cred auth.Credentials, r *http.Re
|
|||||||
Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken),
|
Creds: credentials.NewStaticV4(cred.AccessKey, cred.SecretKey, cred.SessionToken),
|
||||||
Secure: secure,
|
Secure: secure,
|
||||||
Transport: globalRemoteTargetTransport,
|
Transport: globalRemoteTargetTransport,
|
||||||
Region: globalSite.Region,
|
Region: globalSite.Region(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return levent.Event{}, err
|
return levent.Event{}, err
|
||||||
|
@ -686,7 +686,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
case authTypePresigned, authTypeSigned:
|
case authTypePresigned, authTypeSigned:
|
||||||
if s3Error = reqSignatureV4Verify(r, globalSite.Region, serviceS3); s3Error != ErrNone {
|
if s3Error = reqSignatureV4Verify(r, globalSite.Region(), serviceS3); s3Error != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func selfSpeedTest(ctx context.Context, opts speedTestOpts) (res SpeedTestResult
|
|||||||
|
|
||||||
clnt := globalMinioClient
|
clnt := globalMinioClient
|
||||||
if !globalAPIConfig.permitRootAccess() {
|
if !globalAPIConfig.permitRootAccess() {
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
if region == "" {
|
if region == "" {
|
||||||
region = "us-east-1"
|
region = "us-east-1"
|
||||||
}
|
}
|
||||||
|
@ -1135,7 +1135,7 @@ func serverMain(ctx *cli.Context) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
if region == "" {
|
if region == "" {
|
||||||
region = "us-east-1"
|
region = "us-east-1"
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func printServerCommonMsg(apiEndpoints []string) {
|
|||||||
cred := globalActiveCred
|
cred := globalActiveCred
|
||||||
|
|
||||||
// Get saved region.
|
// Get saved region.
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
|
|
||||||
apiEndpointStr := strings.TrimSpace(strings.Join(apiEndpoints, " "))
|
apiEndpointStr := strings.TrimSpace(strings.Join(apiEndpoints, " "))
|
||||||
// Colorize the message and print.
|
// Colorize the message and print.
|
||||||
@ -146,7 +146,7 @@ func printLambdaTargets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arnMsg := color.Blue("Object Lambda ARNs: ")
|
arnMsg := color.Blue("Object Lambda ARNs: ")
|
||||||
for _, arn := range globalLambdaTargetList.List(globalSite.Region) {
|
for _, arn := range globalLambdaTargetList.List(globalSite.Region()) {
|
||||||
arnMsg += color.Bold(fmt.Sprintf("%s ", arn))
|
arnMsg += color.Bold(fmt.Sprintf("%s ", arn))
|
||||||
}
|
}
|
||||||
logger.Info(arnMsg + "\n")
|
logger.Info(arnMsg + "\n")
|
||||||
|
@ -398,7 +398,7 @@ func (f *sftpDriver) Filecmd(r *sftp.Request) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if prefix == "" {
|
if prefix == "" {
|
||||||
return clnt.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{Region: globalSite.Region})
|
return clnt.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{Region: globalSite.Region()})
|
||||||
}
|
}
|
||||||
|
|
||||||
dirPath := buildMinioDir(prefix)
|
dirPath := buildMinioDir(prefix)
|
||||||
|
@ -175,7 +175,7 @@ func compareSignatureV4(sig1, sig2 string) bool {
|
|||||||
// returns ErrNone if the signature matches.
|
// returns ErrNone if the signature matches.
|
||||||
func doesPolicySignatureV4Match(formValues http.Header) (auth.Credentials, APIErrorCode) {
|
func doesPolicySignatureV4Match(formValues http.Header) (auth.Credentials, APIErrorCode) {
|
||||||
// Server region.
|
// Server region.
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
|
|
||||||
// Parse credential tag.
|
// Parse credential tag.
|
||||||
credHeader, s3Err := parseCredentialHeader("Credential="+formValues.Get(xhttp.AmzCredential), region, serviceS3)
|
credHeader, s3Err := parseCredentialHeader("Credential="+formValues.Get(xhttp.AmzCredential), region, serviceS3)
|
||||||
|
@ -111,7 +111,7 @@ func TestDoesPresignedSignatureMatch(t *testing.T) {
|
|||||||
now := UTCNow()
|
now := UTCNow()
|
||||||
credentialTemplate := "%s/%s/%s/s3/aws4_request"
|
credentialTemplate := "%s/%s/%s/s3/aws4_request"
|
||||||
|
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
accessKeyID := globalActiveCred.AccessKey
|
accessKeyID := globalActiveCred.AccessKey
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
queryParams map[string]string
|
queryParams map[string]string
|
||||||
|
@ -677,7 +677,7 @@ func (c *SiteReplicationSys) GetIDPSettings(ctx context.Context) madmin.IDPSetti
|
|||||||
}
|
}
|
||||||
s.OpenID = globalIAMSys.OpenIDConfig.GetSettings()
|
s.OpenID = globalIAMSys.OpenIDConfig.GetSettings()
|
||||||
if s.OpenID.Enabled {
|
if s.OpenID.Enabled {
|
||||||
s.OpenID.Region = globalSite.Region
|
s.OpenID.Region = globalSite.Region()
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func calculateSeedSignature(r *http.Request, trailers bool) (cred auth.Credentia
|
|||||||
v4Auth := req.Header.Get(xhttp.Authorization)
|
v4Auth := req.Header.Get(xhttp.Authorization)
|
||||||
|
|
||||||
// Parse signature version '4' header.
|
// Parse signature version '4' header.
|
||||||
signV4Values, errCode := parseSignV4(v4Auth, globalSite.Region, serviceS3)
|
signV4Values, errCode := parseSignV4(v4Auth, globalSite.Region(), serviceS3)
|
||||||
if errCode != ErrNone {
|
if errCode != ErrNone {
|
||||||
return cred, "", "", time.Time{}, errCode
|
return cred, "", "", time.Time{}, errCode
|
||||||
}
|
}
|
||||||
|
@ -155,12 +155,12 @@ func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (auth.Credentials
|
|||||||
return auth.Credentials{}, ErrAccessDenied
|
return auth.Credentials{}, ErrAccessDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
s3Err := isReqAuthenticated(ctx, r, globalSite.Region, serviceSTS)
|
s3Err := isReqAuthenticated(ctx, r, globalSite.Region(), serviceSTS)
|
||||||
if s3Err != ErrNone {
|
if s3Err != ErrNone {
|
||||||
return auth.Credentials{}, s3Err
|
return auth.Credentials{}, s3Err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, _, s3Err := getReqAccessKeyV4(r, globalSite.Region, serviceSTS)
|
user, _, s3Err := getReqAccessKeyV4(r, globalSite.Region(), serviceSTS)
|
||||||
if s3Err != ErrNone {
|
if s3Err != ErrNone {
|
||||||
return auth.Credentials{}, s3Err
|
return auth.Credentials{}, s3Err
|
||||||
}
|
}
|
||||||
|
@ -750,7 +750,7 @@ func newTestStreamingRequest(method, urlStr string, dataLength, chunkSize int64,
|
|||||||
func assembleStreamingChunks(req *http.Request, body io.ReadSeeker, chunkSize int64,
|
func assembleStreamingChunks(req *http.Request, body io.ReadSeeker, chunkSize int64,
|
||||||
secretKey, signature string, currTime time.Time) (*http.Request, error,
|
secretKey, signature string, currTime time.Time) (*http.Request, error,
|
||||||
) {
|
) {
|
||||||
regionStr := globalSite.Region
|
regionStr := globalSite.Region()
|
||||||
var stream []byte
|
var stream []byte
|
||||||
var buffer []byte
|
var buffer []byte
|
||||||
body.Seek(0, 0)
|
body.Seek(0, 0)
|
||||||
@ -858,7 +858,7 @@ func preSignV4(req *http.Request, accessKeyID, secretAccessKey string, expires i
|
|||||||
return errors.New("Presign cannot be generated without access and secret keys")
|
return errors.New("Presign cannot be generated without access and secret keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
date := UTCNow()
|
date := UTCNow()
|
||||||
scope := getScope(date, region)
|
scope := getScope(date, region)
|
||||||
credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
|
credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
|
||||||
@ -986,7 +986,7 @@ func signRequestV4(req *http.Request, accessKey, secretKey string) error {
|
|||||||
}
|
}
|
||||||
sort.Strings(headers)
|
sort.Strings(headers)
|
||||||
|
|
||||||
region := globalSite.Region
|
region := globalSite.Region()
|
||||||
|
|
||||||
// Get canonical headers.
|
// Get canonical headers.
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/minio/madmin-go/v3"
|
"github.com/minio/madmin-go/v3"
|
||||||
"github.com/minio/minio-go/v7/pkg/set"
|
"github.com/minio/minio-go/v7/pkg/set"
|
||||||
@ -544,10 +545,36 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var siteLK sync.RWMutex
|
||||||
|
|
||||||
// Site - holds site info - name and region.
|
// Site - holds site info - name and region.
|
||||||
type Site struct {
|
type Site struct {
|
||||||
Name string
|
name string
|
||||||
Region string
|
region string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update safe update the new site name and region
|
||||||
|
func (s *Site) Update(n Site) {
|
||||||
|
siteLK.Lock()
|
||||||
|
s.name = n.name
|
||||||
|
s.region = n.region
|
||||||
|
siteLK.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns currently configured site name
|
||||||
|
func (s *Site) Name() string {
|
||||||
|
siteLK.RLock()
|
||||||
|
defer siteLK.RUnlock()
|
||||||
|
|
||||||
|
return s.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Region returns currently configured site region
|
||||||
|
func (s *Site) Region() string {
|
||||||
|
siteLK.RLock()
|
||||||
|
defer siteLK.RUnlock()
|
||||||
|
|
||||||
|
return s.region
|
||||||
}
|
}
|
||||||
|
|
||||||
var validRegionRegex = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9-_-]+$")
|
var validRegionRegex = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9-_-]+$")
|
||||||
@ -590,7 +617,7 @@ func LookupSite(siteKV KVS, regionKV KVS) (s Site, err error) {
|
|||||||
region)
|
region)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Region = region
|
s.region = region
|
||||||
}
|
}
|
||||||
|
|
||||||
name := env.Get(EnvSiteName, siteKV.Get(NameKey))
|
name := env.Get(EnvSiteName, siteKV.Get(NameKey))
|
||||||
@ -601,7 +628,7 @@ func LookupSite(siteKV KVS, regionKV KVS) (s Site, err error) {
|
|||||||
name)
|
name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Name = name
|
s.name = name
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user