Rename replication target handler (#10142)

Rename replication target handler to a generic bucket target handler
master
poornas 4 years ago committed by GitHub
parent 27266f8a54
commit b46ab7e921
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      cmd/admin-bucket-handlers.go
  2. 18
      cmd/admin-router.go
  3. 10
      cmd/bucket-metadata-sys.go
  4. 60
      cmd/bucket-metadata.go
  5. 28
      cmd/bucket-metadata_gen.go
  6. 6
      cmd/bucket-replication.go
  7. 1
      go.mod
  8. 8
      go.sum
  9. 152
      pkg/iam/policy/admin-action.go
  10. 14
      pkg/madmin/examples/bucket-target.go
  11. 54
      pkg/madmin/remote-target-commands.go

@ -32,8 +32,8 @@ import (
)
const (
bucketQuotaConfigFile = "quota.json"
bucketReplicationTargetsFile = "replication-targets.json"
bucketQuotaConfigFile = "quota.json"
bucketTargetsFile = "bucket-targets.json"
)
// PutBucketQuotaConfigHandler - PUT Bucket quota configuration.
@ -121,16 +121,16 @@ func (a adminAPIHandlers) GetBucketQuotaConfigHandler(w http.ResponseWriter, r *
writeSuccessResponseJSON(w, configData)
}
// SetBucketReplicationTargetHandler - sets a replication target for bucket
func (a adminAPIHandlers) SetBucketReplicationTargetHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "SetBucketReplicationTarget")
// SetBucketTargetHandler - sets a remote target for bucket
func (a adminAPIHandlers) SetBucketTargetHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "SetBucketTarget")
defer logger.AuditLog(w, r, "SetBucketReplicationTarget", mustGetClaimsFromToken(r))
defer logger.AuditLog(w, r, "SetBucketTarget", mustGetClaimsFromToken(r))
vars := mux.Vars(r)
bucket := vars["bucket"]
// Get current object layer instance.
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.SetBucketReplicationTargetAction)
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.SetBucketTargetAction)
if objectAPI == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return
@ -151,11 +151,6 @@ func (a adminAPIHandlers) SetBucketReplicationTargetHandler(w http.ResponseWrite
return
}
if versioned := globalBucketVersioningSys.Enabled(bucket); !versioned {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrReplicationBucketNeedsVersioningError), r.URL)
return
}
cred, _, _, s3Err := validateAdminSignature(ctx, r, "")
if s3Err != ErrNone {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
@ -169,7 +164,7 @@ func (a adminAPIHandlers) SetBucketReplicationTargetHandler(w http.ResponseWrite
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErrWithErr(ErrAdminConfigBadJSON, err), r.URL)
return
}
var target madmin.BucketReplicationTarget
var target madmin.BucketTarget
if err = json.Unmarshal(reqBytes, &target); err != nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErrWithErr(ErrAdminConfigBadJSON, err), r.URL)
return
@ -180,7 +175,7 @@ func (a adminAPIHandlers) SetBucketReplicationTargetHandler(w http.ResponseWrite
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErrWithErr(ErrAdminConfigBadJSON, err), r.URL)
return
}
if err = globalBucketMetadataSys.Update(bucket, bucketReplicationTargetsFile, tgtBytes); err != nil {
if err = globalBucketMetadataSys.Update(bucket, bucketTargetsFile, tgtBytes); err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
return
}
@ -193,15 +188,15 @@ func (a adminAPIHandlers) SetBucketReplicationTargetHandler(w http.ResponseWrite
writeSuccessResponseHeadersOnly(w)
}
// GetBucketReplicationTargetsHandler - gets bucket replication targets for a particular bucket
func (a adminAPIHandlers) GetBucketReplicationTargetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketReplicationTarget")
// GetBucketTargetHandler - gets remote target for a particular bucket
func (a adminAPIHandlers) GetBucketTargetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketTarget")
defer logger.AuditLog(w, r, "GetBucketReplicationTarget", mustGetClaimsFromToken(r))
defer logger.AuditLog(w, r, "GetBucketTarget", mustGetClaimsFromToken(r))
vars := mux.Vars(r)
bucket := vars["bucket"]
// Get current object layer instance.
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketReplicationTargetAction)
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketTargetAction)
if objectAPI == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return
@ -214,11 +209,11 @@ func (a adminAPIHandlers) GetBucketReplicationTargetsHandler(w http.ResponseWrit
}
// remove secretKey from creds
var tgt madmin.BucketReplicationTarget
var tgt madmin.BucketTarget
if !target.Empty() {
var creds auth.Credentials
creds.AccessKey = target.Credentials.AccessKey
tgt = madmin.BucketReplicationTarget{Endpoint: target.Endpoint, TargetBucket: target.TargetBucket, Credentials: &creds, Arn: target.Arn}
tgt = madmin.BucketTarget{Endpoint: target.Endpoint, TargetBucket: target.TargetBucket, Credentials: &creds, Arn: target.Arn}
}
data, err := json.Marshal(tgt)
if err != nil {
@ -229,15 +224,15 @@ func (a adminAPIHandlers) GetBucketReplicationTargetsHandler(w http.ResponseWrit
writeSuccessResponseJSON(w, data)
}
// GetBucketReplicationARNHandler - gets replication ARN for a particular remote
func (a adminAPIHandlers) GetBucketReplicationARNHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketReplicationARN")
// GetBucketTargetARNHandler - gets replication ARN for a particular remote
func (a adminAPIHandlers) GetBucketTargetARNHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetBucketTargetARN")
defer logger.AuditLog(w, r, "GetBucketReplicationARN", mustGetClaimsFromToken(r))
defer logger.AuditLog(w, r, "GetBucketTargetARN", mustGetClaimsFromToken(r))
vars := mux.Vars(r)
rURL := vars["url"]
// Get current object layer instance.
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketReplicationTargetAction)
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketTargetAction)
if objectAPI == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return

@ -182,15 +182,15 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool)
httpTraceHdrs(adminAPI.PutBucketQuotaConfigHandler)).Queries("bucket", "{bucket:.*}")
}
// Bucket replication operations
// GetBucketReplicationTargetHandler
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-replication-target").HandlerFunc(
httpTraceHdrs(adminAPI.GetBucketReplicationTargetsHandler)).Queries("bucket", "{bucket:.*}")
// GetBucketReplicationARN Handler
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-replication-arn").HandlerFunc(
httpTraceHdrs(adminAPI.GetBucketReplicationARNHandler)).Queries("url", "{url:.*}")
// SetBucketReplicationTargetHandler
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-bucket-replication-target").HandlerFunc(
httpTraceHdrs(adminAPI.SetBucketReplicationTargetHandler)).Queries("bucket", "{bucket:.*}")
// GetBucketTargetHandler
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-target").HandlerFunc(
httpTraceHdrs(adminAPI.GetBucketTargetsHandler)).Queries("bucket", "{bucket:.*}")
// GetBucketTargetARN Handler
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-target-arn").HandlerFunc(
httpTraceHdrs(adminAPI.GetBucketTargetARNHandler)).Queries("url", "{url:.*}")
// SetBucketTargetHandler
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-bucket-target").HandlerFunc(
httpTraceHdrs(adminAPI.SetBucketTargetHandler)).Queries("bucket", "{bucket:.*}")
}
// -- Top APIs --

@ -156,8 +156,8 @@ func (sys *BucketMetadataSys) Update(bucket string, configFile string, configDat
meta.QuotaConfigJSON = configData
case bucketReplicationConfig:
meta.ReplicationConfigXML = configData
case bucketReplicationTargetsFile:
meta.ReplicationTargetsConfigJSON = configData
case bucketTargetsFile:
meta.BucketTargetsConfigJSON = configData
default:
return fmt.Errorf("Unknown bucket %s metadata update requested %s", bucket, configFile)
}
@ -342,15 +342,15 @@ func (sys *BucketMetadataSys) GetReplicationConfig(ctx context.Context, bucket s
// GetReplicationTargetConfig returns configured bucket replication target for this bucket
// The returned object may not be modified.
func (sys *BucketMetadataSys) GetReplicationTargetConfig(bucket string) (*madmin.BucketReplicationTarget, error) {
func (sys *BucketMetadataSys) GetReplicationTargetConfig(bucket string) (*madmin.BucketTarget, error) {
meta, err := sys.GetConfig(bucket)
if err != nil {
return nil, err
}
if meta.replicationTargetConfig == nil {
if meta.bucketTargetConfig == nil {
return nil, BucketReplicationTargetNotFound{Bucket: bucket}
}
return meta.replicationTargetConfig, nil
return meta.bucketTargetConfig, nil
}
// GetConfig returns a specific configuration from the bucket metadata.

@ -61,31 +61,31 @@ var (
// bucketMetadataFormat refers to the format.
// bucketMetadataVersion can be used to track a rolling upgrade of a field.
type BucketMetadata struct {
Name string
Created time.Time
LockEnabled bool // legacy not used anymore.
PolicyConfigJSON []byte
NotificationConfigXML []byte
LifecycleConfigXML []byte
ObjectLockConfigXML []byte
VersioningConfigXML []byte
EncryptionConfigXML []byte
TaggingConfigXML []byte
QuotaConfigJSON []byte
ReplicationConfigXML []byte
ReplicationTargetsConfigJSON []byte
Name string
Created time.Time
LockEnabled bool // legacy not used anymore.
PolicyConfigJSON []byte
NotificationConfigXML []byte
LifecycleConfigXML []byte
ObjectLockConfigXML []byte
VersioningConfigXML []byte
EncryptionConfigXML []byte
TaggingConfigXML []byte
QuotaConfigJSON []byte
ReplicationConfigXML []byte
BucketTargetsConfigJSON []byte
// Unexported fields. Must be updated atomically.
policyConfig *policy.Policy
notificationConfig *event.Config
lifecycleConfig *lifecycle.Lifecycle
objectLockConfig *objectlock.Config
versioningConfig *versioning.Versioning
sseConfig *bucketsse.BucketSSEConfig
taggingConfig *tags.Tags
quotaConfig *madmin.BucketQuota
replicationConfig *replication.Config
replicationTargetConfig *madmin.BucketReplicationTarget
policyConfig *policy.Policy
notificationConfig *event.Config
lifecycleConfig *lifecycle.Lifecycle
objectLockConfig *objectlock.Config
versioningConfig *versioning.Versioning
sseConfig *bucketsse.BucketSSEConfig
taggingConfig *tags.Tags
quotaConfig *madmin.BucketQuota
replicationConfig *replication.Config
bucketTargetConfig *madmin.BucketTarget
}
// newBucketMetadata creates BucketMetadata with the supplied name and Created to Now.
@ -100,7 +100,7 @@ func newBucketMetadata(name string) BucketMetadata {
versioningConfig: &versioning.Versioning{
XMLNS: "http://s3.amazonaws.com/doc/2006-03-01/",
},
replicationTargetConfig: &madmin.BucketReplicationTarget{},
bucketTargetConfig: &madmin.BucketTarget{},
}
}
@ -227,12 +227,12 @@ func (b *BucketMetadata) parseAllConfigs(ctx context.Context, objectAPI ObjectLa
b.replicationConfig = nil
}
if len(b.ReplicationTargetsConfigJSON) != 0 {
if err = json.Unmarshal(b.ReplicationTargetsConfigJSON, b.replicationTargetConfig); err != nil {
if len(b.BucketTargetsConfigJSON) != 0 {
if err = json.Unmarshal(b.BucketTargetsConfigJSON, b.bucketTargetConfig); err != nil {
return err
}
} else {
b.replicationTargetConfig = &madmin.BucketReplicationTarget{}
b.bucketTargetConfig = &madmin.BucketTarget{}
}
return nil
}
@ -247,7 +247,7 @@ func (b *BucketMetadata) convertLegacyConfigs(ctx context.Context, objectAPI Obj
bucketSSEConfig,
bucketTaggingConfig,
bucketReplicationConfig,
bucketReplicationTargetsFile,
bucketTargetsFile,
objectLockConfig,
}
@ -306,8 +306,8 @@ func (b *BucketMetadata) convertLegacyConfigs(ctx context.Context, objectAPI Obj
b.QuotaConfigJSON = configData
case bucketReplicationConfig:
b.ReplicationConfigXML = configData
case bucketReplicationTargetsFile:
b.ReplicationTargetsConfigJSON = configData
case bucketTargetsFile:
b.BucketTargetsConfigJSON = configData
}
}

@ -96,10 +96,10 @@ func (z *BucketMetadata) DecodeMsg(dc *msgp.Reader) (err error) {
err = msgp.WrapError(err, "ReplicationConfigXML")
return
}
case "ReplicationTargetsConfigJSON":
z.ReplicationTargetsConfigJSON, err = dc.ReadBytes(z.ReplicationTargetsConfigJSON)
case "BucketTargetsConfigJSON":
z.BucketTargetsConfigJSON, err = dc.ReadBytes(z.BucketTargetsConfigJSON)
if err != nil {
err = msgp.WrapError(err, "ReplicationTargetsConfigJSON")
err = msgp.WrapError(err, "BucketTargetsConfigJSON")
return
}
default:
@ -236,14 +236,14 @@ func (z *BucketMetadata) EncodeMsg(en *msgp.Writer) (err error) {
err = msgp.WrapError(err, "ReplicationConfigXML")
return
}
// write "ReplicationTargetsConfigJSON"
err = en.Append(0xbc, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e)
// write "BucketTargetsConfigJSON"
err = en.Append(0xb7, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e)
if err != nil {
return
}
err = en.WriteBytes(z.ReplicationTargetsConfigJSON)
err = en.WriteBytes(z.BucketTargetsConfigJSON)
if err != nil {
err = msgp.WrapError(err, "ReplicationTargetsConfigJSON")
err = msgp.WrapError(err, "BucketTargetsConfigJSON")
return
}
return
@ -289,9 +289,9 @@ func (z *BucketMetadata) MarshalMsg(b []byte) (o []byte, err error) {
// string "ReplicationConfigXML"
o = append(o, 0xb4, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x58, 0x4d, 0x4c)
o = msgp.AppendBytes(o, z.ReplicationConfigXML)
// string "ReplicationTargetsConfigJSON"
o = append(o, 0xbc, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e)
o = msgp.AppendBytes(o, z.ReplicationTargetsConfigJSON)
// string "BucketTargetsConfigJSON"
o = append(o, 0xb7, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e)
o = msgp.AppendBytes(o, z.BucketTargetsConfigJSON)
return
}
@ -385,10 +385,10 @@ func (z *BucketMetadata) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "ReplicationConfigXML")
return
}
case "ReplicationTargetsConfigJSON":
z.ReplicationTargetsConfigJSON, bts, err = msgp.ReadBytesBytes(bts, z.ReplicationTargetsConfigJSON)
case "BucketTargetsConfigJSON":
z.BucketTargetsConfigJSON, bts, err = msgp.ReadBytesBytes(bts, z.BucketTargetsConfigJSON)
if err != nil {
err = msgp.WrapError(err, "ReplicationTargetsConfigJSON")
err = msgp.WrapError(err, "BucketTargetsConfigJSON")
return
}
default:
@ -405,6 +405,6 @@ func (z *BucketMetadata) UnmarshalMsg(bts []byte) (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *BucketMetadata) Msgsize() (s int) {
s = 1 + 5 + msgp.StringPrefixSize + len(z.Name) + 8 + msgp.TimeSize + 12 + msgp.BoolSize + 17 + msgp.BytesPrefixSize + len(z.PolicyConfigJSON) + 22 + msgp.BytesPrefixSize + len(z.NotificationConfigXML) + 19 + msgp.BytesPrefixSize + len(z.LifecycleConfigXML) + 20 + msgp.BytesPrefixSize + len(z.ObjectLockConfigXML) + 20 + msgp.BytesPrefixSize + len(z.VersioningConfigXML) + 20 + msgp.BytesPrefixSize + len(z.EncryptionConfigXML) + 17 + msgp.BytesPrefixSize + len(z.TaggingConfigXML) + 16 + msgp.BytesPrefixSize + len(z.QuotaConfigJSON) + 21 + msgp.BytesPrefixSize + len(z.ReplicationConfigXML) + 29 + msgp.BytesPrefixSize + len(z.ReplicationTargetsConfigJSON)
s = 1 + 5 + msgp.StringPrefixSize + len(z.Name) + 8 + msgp.TimeSize + 12 + msgp.BoolSize + 17 + msgp.BytesPrefixSize + len(z.PolicyConfigJSON) + 22 + msgp.BytesPrefixSize + len(z.NotificationConfigXML) + 19 + msgp.BytesPrefixSize + len(z.LifecycleConfigXML) + 20 + msgp.BytesPrefixSize + len(z.ObjectLockConfigXML) + 20 + msgp.BytesPrefixSize + len(z.VersioningConfigXML) + 20 + msgp.BytesPrefixSize + len(z.EncryptionConfigXML) + 17 + msgp.BytesPrefixSize + len(z.TaggingConfigXML) + 16 + msgp.BytesPrefixSize + len(z.QuotaConfigJSON) + 21 + msgp.BytesPrefixSize + len(z.ReplicationConfigXML) + 24 + msgp.BytesPrefixSize + len(z.BucketTargetsConfigJSON)
return
}

@ -60,7 +60,7 @@ func (sys *BucketReplicationSys) GetConfig(ctx context.Context, bucketName strin
}
// SetTarget - sets a new minio-go client replication target for this bucket.
func (sys *BucketReplicationSys) SetTarget(ctx context.Context, bucket string, tgt *madmin.BucketReplicationTarget) error {
func (sys *BucketReplicationSys) SetTarget(ctx context.Context, bucket string, tgt *madmin.BucketTarget) error {
if globalIsGateway {
return nil
}
@ -184,7 +184,7 @@ var getReplicationTargetInstanceTransport http.RoundTripper
var getReplicationTargetInstanceTransportOnce sync.Once
// Returns a minio-go Client configured to access remote host described in replication target config.
var getReplicationTargetClient = func(tcfg *madmin.BucketReplicationTarget) (*miniogo.Core, error) {
var getReplicationTargetClient = func(tcfg *madmin.BucketTarget) (*miniogo.Core, error) {
config := tcfg.Credentials
// if Signature version '4' use NewV4 directly.
creds := credentials.NewStaticV4(config.AccessKey, config.SecretKey, "")
@ -198,7 +198,7 @@ var getReplicationTargetClient = func(tcfg *madmin.BucketReplicationTarget) (*mi
})
core, err := miniogo.NewCore(tcfg.Endpoint, &miniogo.Options{
Creds: creds,
Secure: tcfg.IsSSL,
Secure: tcfg.Secure,
Transport: getReplicationTargetInstanceTransport,
})
return core, err

@ -84,6 +84,7 @@ require (
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae
golang.org/x/text v0.3.3 // indirect
golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99 // indirect
google.golang.org/api v0.5.0
gopkg.in/jcmturner/gokrb5.v7 v7.3.0
gopkg.in/ldap.v3 v3.0.3

@ -445,6 +445,7 @@ github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd/v3 v3.3.0-rc.0.0.20200707003333-58bb8ae09f8e h1:HZQLoe71Q24wVyDrGBRcVuogx32U+cPlcm/WoSLUI6c=
@ -485,6 +486,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -499,6 +502,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -511,6 +515,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -561,6 +567,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99 h1:OHn441rq5CeM5r1xJ0OmY7lfdTvnedi6k+vQiI7G9b8=
golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

@ -108,12 +108,12 @@ const (
// GetBucketQuotaAdminAction - allow getting bucket quota
GetBucketQuotaAdminAction = "admin:GetBucketQuota"
// Bucket Replication admin Actions
// Bucket Target admin Actions
// SetBucketReplicationTargetAction - allow setting bucket replication target
SetBucketReplicationTargetAction = "admin:SetBucketReplicationTarget"
// GetBucketReplicationTargetAction - allow getting bucket replication targets
GetBucketReplicationTargetAction = "admin:GetBucketReplicationTarget"
// SetBucketTargetAction - allow setting bucket target
SetBucketTargetAction = "admin:SetBucketTarget"
// GetBucketTargetAction - allow getting bucket targets
GetBucketTargetAction = "admin:GetBucketTarget"
// AllAdminActions - provides all admin permissions
AllAdminActions = "admin:*"
@ -121,42 +121,42 @@ const (
// List of all supported admin actions.
var supportedAdminActions = map[AdminAction]struct{}{
HealAdminAction: {},
StorageInfoAdminAction: {},
DataUsageInfoAdminAction: {},
TopLocksAdminAction: {},
ProfilingAdminAction: {},
TraceAdminAction: {},
ConsoleLogAdminAction: {},
KMSKeyStatusAdminAction: {},
ServerInfoAdminAction: {},
OBDInfoAdminAction: {},
ServerUpdateAdminAction: {},
ServiceRestartAdminAction: {},
ServiceStopAdminAction: {},
ConfigUpdateAdminAction: {},
CreateUserAdminAction: {},
DeleteUserAdminAction: {},
ListUsersAdminAction: {},
EnableUserAdminAction: {},
DisableUserAdminAction: {},
GetUserAdminAction: {},
AddUserToGroupAdminAction: {},
RemoveUserFromGroupAdminAction: {},
GetGroupAdminAction: {},
ListGroupsAdminAction: {},
EnableGroupAdminAction: {},
DisableGroupAdminAction: {},
CreatePolicyAdminAction: {},
DeletePolicyAdminAction: {},
GetPolicyAdminAction: {},
AttachPolicyAdminAction: {},
ListUserPoliciesAdminAction: {},
SetBucketQuotaAdminAction: {},
GetBucketQuotaAdminAction: {},
SetBucketReplicationTargetAction: {},
GetBucketReplicationTargetAction: {},
AllAdminActions: {},
HealAdminAction: {},
StorageInfoAdminAction: {},
DataUsageInfoAdminAction: {},
TopLocksAdminAction: {},
ProfilingAdminAction: {},
TraceAdminAction: {},
ConsoleLogAdminAction: {},
KMSKeyStatusAdminAction: {},
ServerInfoAdminAction: {},
OBDInfoAdminAction: {},
ServerUpdateAdminAction: {},
ServiceRestartAdminAction: {},
ServiceStopAdminAction: {},
ConfigUpdateAdminAction: {},
CreateUserAdminAction: {},
DeleteUserAdminAction: {},
ListUsersAdminAction: {},
EnableUserAdminAction: {},
DisableUserAdminAction: {},
GetUserAdminAction: {},
AddUserToGroupAdminAction: {},
RemoveUserFromGroupAdminAction: {},
GetGroupAdminAction: {},
ListGroupsAdminAction: {},
EnableGroupAdminAction: {},
DisableGroupAdminAction: {},
CreatePolicyAdminAction: {},
DeletePolicyAdminAction: {},
GetPolicyAdminAction: {},
AttachPolicyAdminAction: {},
ListUserPoliciesAdminAction: {},
SetBucketQuotaAdminAction: {},
GetBucketQuotaAdminAction: {},
SetBucketTargetAction: {},
GetBucketTargetAction: {},
AllAdminActions: {},
}
// IsValid - checks if action is valid or not.
@ -167,39 +167,39 @@ func (action AdminAction) IsValid() bool {
// adminActionConditionKeyMap - holds mapping of supported condition key for an action.
var adminActionConditionKeyMap = map[Action]condition.KeySet{
AllAdminActions: condition.NewKeySet(condition.AllSupportedAdminKeys...),
HealAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
StorageInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServerInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DataUsageInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
OBDInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
TopLocksAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ProfilingAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
TraceAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ConsoleLogAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
KMSKeyStatusAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServerUpdateAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServiceRestartAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServiceStopAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ConfigUpdateAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
CreateUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DeleteUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListUsersAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
EnableUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DisableUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
AddUserToGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
RemoveUserFromGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListGroupsAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
EnableGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DisableGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
CreatePolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DeletePolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetPolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
AttachPolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListUserPoliciesAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
SetBucketQuotaAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetBucketQuotaAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
SetBucketReplicationTargetAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetBucketReplicationTargetAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
AllAdminActions: condition.NewKeySet(condition.AllSupportedAdminKeys...),
HealAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
StorageInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServerInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DataUsageInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
OBDInfoAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
TopLocksAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ProfilingAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
TraceAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ConsoleLogAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
KMSKeyStatusAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServerUpdateAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServiceRestartAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ServiceStopAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ConfigUpdateAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
CreateUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DeleteUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListUsersAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
EnableUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DisableUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetUserAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
AddUserToGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
RemoveUserFromGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListGroupsAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
EnableGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DisableGroupAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
CreatePolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
DeletePolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetPolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
AttachPolicyAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
ListUserPoliciesAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
SetBucketQuotaAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetBucketQuotaAdminAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
SetBucketTargetAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
GetBucketTargetAction: condition.NewKeySet(condition.AllSupportedAdminKeys...),
}

@ -42,19 +42,19 @@ func main() {
if err != nil {
log.Fatalln(err)
}
target := madmin.BucketReplicationTarget{Endpoint: "site2:9000", Credentials: creds, TargetBucket: "destbucket", IsSSL: false}
// Set bucket replication target
if err := madmClnt.SetBucketReplicationTarget(ctx, "srcbucket", &target); err != nil {
target := madmin.BucketTarget{Endpoint: "site2:9000", Credentials: creds, TargetBucket: "destbucket", IsSSL: false}
// Set bucket target
if err := madmClnt.SetBucketTarget(ctx, "srcbucket", &target); err != nil {
log.Fatalln(err)
}
// Get bucket replication target
target, err = madmClnt.GetBucketReplicationTarget(ctx, "srcbucket")
// Get bucket target
target, err = madmClnt.GetBucketTarget(ctx, "srcbucket")
if err != nil {
log.Fatalln(err)
}
// Remove bucket replication target
if err := madmClnt.SetBucketReplicationTarget(ctx, "srcbucket", nil); err != nil {
// Remove bucket target
if err := madmClnt.SetBucketTarget(ctx, "srcbucket", nil); err != nil {
log.Fatalln(err)
}

@ -29,46 +29,60 @@ import (
"github.com/minio/minio/pkg/auth"
)
// BucketReplicationTarget represents the target bucket and site to be replicated to.
type BucketReplicationTarget struct {
// ArnType represents bucket ARN type
type ArnType string
const (
// Replication specifies a ARN type of replication
Replication ArnType = "replication"
)
// IsValid returns true if ARN type is replication
func (t ArnType) IsValid() bool {
return t == Replication
}
// BucketTarget represents the target bucket and site association.
type BucketTarget struct {
Endpoint string `json:"endpoint"`
Credentials *auth.Credentials `json:"credentials"`
TargetBucket string `json:"targetbucket"`
IsSSL bool `json:"isssl"`
Secure bool `json:"secure"`
Path string `json:"path,omitempty"`
API string `json:"api,omitempty"`
Arn string `json:"arn,omitempty"`
Type ArnType `json:"type"`
}
// URL returns replication target url
func (t BucketReplicationTarget) URL() string {
func (t BucketTarget) URL() string {
scheme := "http"
if t.IsSSL {
if t.Secure {
scheme = "https"
}
return fmt.Sprintf("%s://%s", scheme, t.Endpoint)
}
// Empty returns true if struct is empty.
func (t BucketReplicationTarget) Empty() bool {
func (t BucketTarget) Empty() bool {
return t.String() == "" || t.Credentials == nil
}
func (t *BucketReplicationTarget) String() string {
func (t *BucketTarget) String() string {
return fmt.Sprintf("%s %s", t.Endpoint, t.TargetBucket)
}
// GetBucketReplicationTarget - gets replication target for this bucket
func (adm *AdminClient) GetBucketReplicationTarget(ctx context.Context, bucket string) (target BucketReplicationTarget, err error) {
// GetBucketTarget - gets target for this bucket
func (adm *AdminClient) GetBucketTarget(ctx context.Context, bucket string) (target BucketTarget, err error) {
queryValues := url.Values{}
queryValues.Set("bucket", bucket)
reqData := requestData{
relPath: adminAPIPrefix + "/get-bucket-replication-target",
relPath: adminAPIPrefix + "/get-bucket-target",
queryValues: queryValues,
}
// Execute GET on /minio/admin/v3/get-bucket-replication-target
// Execute GET on /minio/admin/v3/get-bucket-target
resp, err := adm.executeMethod(ctx, http.MethodGet, reqData)
defer closeResponse(resp)
@ -88,13 +102,13 @@ func (adm *AdminClient) GetBucketReplicationTarget(ctx context.Context, bucket s
return target, err
}
if target.Empty() {
return target, errors.New("No Replication target configured")
return target, errors.New("No bucket target configured")
}
return target, nil
}
// SetBucketReplicationTarget sets up a replication target for this bucket
func (adm *AdminClient) SetBucketReplicationTarget(ctx context.Context, bucket string, target *BucketReplicationTarget) error {
// SetBucketTarget sets up a remote target for this bucket
func (adm *AdminClient) SetBucketTarget(ctx context.Context, bucket string, target *BucketTarget) error {
data, err := json.Marshal(target)
if err != nil {
return err
@ -107,7 +121,7 @@ func (adm *AdminClient) SetBucketReplicationTarget(ctx context.Context, bucket s
queryValues.Set("bucket", bucket)
reqData := requestData{
relPath: adminAPIPrefix + "/set-bucket-replication-target",
relPath: adminAPIPrefix + "/set-bucket-target",
queryValues: queryValues,
content: encData,
}
@ -127,17 +141,17 @@ func (adm *AdminClient) SetBucketReplicationTarget(ctx context.Context, bucket s
return nil
}
// GetBucketReplicationARN - gets replication Arn for this remote
func (adm *AdminClient) GetBucketReplicationARN(ctx context.Context, rURL string) (arn string, err error) {
// GetBucketTargetARN - gets Arn for this remote target
func (adm *AdminClient) GetBucketTargetARN(ctx context.Context, rURL string) (arn string, err error) {
queryValues := url.Values{}
queryValues.Set("url", rURL)
reqData := requestData{
relPath: adminAPIPrefix + "/get-bucket-replication-arn",
relPath: adminAPIPrefix + "/get-bucket-target-arn",
queryValues: queryValues,
}
// Execute GET on /minio/admin/v3/list-bucket-replication-arn
// Execute GET on /minio/admin/v3/list-bucket-target-arn
resp, err := adm.executeMethod(ctx, http.MethodGet, reqData)
defer closeResponse(resp)
@ -157,7 +171,7 @@ func (adm *AdminClient) GetBucketReplicationARN(ctx context.Context, rURL string
return arn, err
}
if arn == "" {
return arn, fmt.Errorf("Missing Replication ARN")
return arn, fmt.Errorf("Missing target ARN")
}
return arn, nil
}
Loading…
Cancel
Save