[gateway] Remove policy reload, instead read policy from backend (#7727)

Inconsistencies can arise after applying bucket policies in
gateway mode, since all gateway instances do not share a
common shared state. This is by design to keep gateway as
shared nothing architecture.

This PR fixes such inconsistencies by reloading policy
if any from the backend.

Fixes #7723
master
Harshavardhana 6 years ago committed by GitHub
parent 1ce2d29bbb
commit 0cfd5a21ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      cmd/gateway-main.go
  2. 5
      cmd/globals.go
  3. 36
      cmd/policy.go

@ -304,6 +304,9 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
printGatewayStartupMessage(getAPIEndpoints(), gatewayName) printGatewayStartupMessage(getAPIEndpoints(), gatewayName)
} }
// Set when gateway is enabled
globalIsGateway = true
// Set uptime time after object layer has initialized. // Set uptime time after object layer has initialized.
globalBootTime = UTCNow() globalBootTime = UTCNow()

@ -82,8 +82,6 @@ const (
// GlobalMultipartCleanupInterval - Cleanup interval when the stale multipart cleanup is initiated. // GlobalMultipartCleanupInterval - Cleanup interval when the stale multipart cleanup is initiated.
GlobalMultipartCleanupInterval = time.Hour * 24 // 24 hrs. GlobalMultipartCleanupInterval = time.Hour * 24 // 24 hrs.
// Refresh interval to update in-memory bucket policy cache.
globalRefreshBucketPolicyInterval = 5 * time.Minute
// Refresh interval to update in-memory iam config cache. // Refresh interval to update in-memory iam config cache.
globalRefreshIAMInterval = 5 * time.Minute globalRefreshIAMInterval = 5 * time.Minute
@ -111,6 +109,9 @@ var (
// Indicates if the running minio server is an erasure-code backend. // Indicates if the running minio server is an erasure-code backend.
globalIsXL = false globalIsXL = false
// Indicates if the running minio is in gateway mode.
globalIsGateway = false
// This flag is set to 'true' by default // This flag is set to 'true' by default
globalIsBrowserEnabled = true globalIsBrowserEnabled = true

@ -25,7 +25,6 @@ import (
"path" "path"
"strings" "strings"
"sync" "sync"
"time"
miniogopolicy "github.com/minio/minio-go/v6/pkg/policy" miniogopolicy "github.com/minio/minio-go/v6/pkg/policy"
"github.com/minio/minio-go/v6/pkg/set" "github.com/minio/minio-go/v6/pkg/set"
@ -61,6 +60,11 @@ func (sys *PolicySys) removeDeletedBuckets(bucketInfos []BucketInfo) {
// Set - sets policy to given bucket name. If policy is empty, existing policy is removed. // Set - sets policy to given bucket name. If policy is empty, existing policy is removed.
func (sys *PolicySys) Set(bucketName string, policy policy.Policy) { func (sys *PolicySys) Set(bucketName string, policy policy.Policy) {
if globalIsGateway {
// Set policy is a non-op under gateway mode.
return
}
sys.Lock() sys.Lock()
defer sys.Unlock() defer sys.Unlock()
@ -84,10 +88,22 @@ func (sys *PolicySys) IsAllowed(args policy.Args) bool {
sys.RLock() sys.RLock()
defer sys.RUnlock() defer sys.RUnlock()
if globalIsGateway {
// When gateway is enabled, no cached value
// is used to validate bucket policies.
objAPI := newObjectLayerFn()
if objAPI != nil {
config, err := objAPI.GetBucketPolicy(context.Background(), args.BucketName)
if err == nil {
return config.IsAllowed(args)
}
}
} else {
// If policy is available for given bucket, check the policy. // If policy is available for given bucket, check the policy.
if p, found := sys.bucketPolicyMap[args.BucketName]; found { if p, found := sys.bucketPolicyMap[args.BucketName]; found {
return p.IsAllowed(args) return p.IsAllowed(args)
} }
}
// As policy is not available for given bucket name, returns IsOwner i.e. // As policy is not available for given bucket name, returns IsOwner i.e.
// operation is allowed only for owner. // operation is allowed only for owner.
@ -135,21 +151,11 @@ func (sys *PolicySys) Init(objAPI ObjectLayer) error {
return errInvalidArgument return errInvalidArgument
} }
defer func() { // In gateway mode, we don't need to load the policies
// Refresh PolicySys in background. // from the backend.
go func() { if globalIsGateway {
ticker := time.NewTicker(globalRefreshBucketPolicyInterval) return nil
defer ticker.Stop()
for {
select {
case <-GlobalServiceDoneCh:
return
case <-ticker.C:
sys.refresh(objAPI)
}
} }
}()
}()
doneCh := make(chan struct{}) doneCh := make(chan struct{})
defer close(doneCh) defer close(doneCh)

Loading…
Cancel
Save