mirror of
https://github.com/minio/minio.git
synced 2025-01-12 15:33:22 -05:00
Generalize error messages for remote targets (#10638)
This is to allow remote targets to be generalized for replication/ILM transition Also adding a field in BucketTarget to identify a remote target with a label.
This commit is contained in:
parent
ed6d2a100f
commit
907a171edd
@ -180,19 +180,19 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool)
|
|||||||
// PutBucketQuotaConfig
|
// PutBucketQuotaConfig
|
||||||
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-bucket-quota").HandlerFunc(
|
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-bucket-quota").HandlerFunc(
|
||||||
httpTraceHdrs(adminAPI.PutBucketQuotaConfigHandler)).Queries("bucket", "{bucket:.*}")
|
httpTraceHdrs(adminAPI.PutBucketQuotaConfigHandler)).Queries("bucket", "{bucket:.*}")
|
||||||
}
|
|
||||||
// Bucket replication operations
|
|
||||||
// GetBucketTargetHandler
|
|
||||||
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-remote-targets").HandlerFunc(
|
|
||||||
httpTraceHdrs(adminAPI.ListRemoteTargetsHandler)).Queries("bucket", "{bucket:.*}", "type", "{type:.*}")
|
|
||||||
// SetRemoteTargetHandler
|
|
||||||
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-remote-target").HandlerFunc(
|
|
||||||
httpTraceHdrs(adminAPI.SetRemoteTargetHandler)).Queries("bucket", "{bucket:.*}")
|
|
||||||
// SetRemoteTargetHandler
|
|
||||||
adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-remote-target").HandlerFunc(
|
|
||||||
httpTraceHdrs(adminAPI.RemoveRemoteTargetHandler)).Queries("bucket", "{bucket:.*}", "arn", "{arn:.*}")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Bucket replication operations
|
||||||
|
// GetBucketTargetHandler
|
||||||
|
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-remote-targets").HandlerFunc(
|
||||||
|
httpTraceHdrs(adminAPI.ListRemoteTargetsHandler)).Queries("bucket", "{bucket:.*}", "type", "{type:.*}")
|
||||||
|
// SetRemoteTargetHandler
|
||||||
|
adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-remote-target").HandlerFunc(
|
||||||
|
httpTraceHdrs(adminAPI.SetRemoteTargetHandler)).Queries("bucket", "{bucket:.*}")
|
||||||
|
// SetRemoteTargetHandler
|
||||||
|
adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-remote-target").HandlerFunc(
|
||||||
|
httpTraceHdrs(adminAPI.RemoveRemoteTargetHandler)).Queries("bucket", "{bucket:.*}", "arn", "{arn:.*}")
|
||||||
|
}
|
||||||
|
}
|
||||||
// -- Top APIs --
|
// -- Top APIs --
|
||||||
// Top locks
|
// Top locks
|
||||||
if globalIsDistErasure {
|
if globalIsDistErasure {
|
||||||
|
@ -106,16 +106,17 @@ const (
|
|||||||
ErrNoSuchCORSConfiguration
|
ErrNoSuchCORSConfiguration
|
||||||
ErrNoSuchWebsiteConfiguration
|
ErrNoSuchWebsiteConfiguration
|
||||||
ErrReplicationConfigurationNotFoundError
|
ErrReplicationConfigurationNotFoundError
|
||||||
ErrReplicationDestinationNotFoundError
|
ErrRemoteDestinationNotFoundError
|
||||||
ErrReplicationDestinationMissingLock
|
ErrReplicationDestinationMissingLock
|
||||||
ErrReplicationTargetNotFoundError
|
ErrRemoteTargetNotFoundError
|
||||||
ErrReplicationRemoteConnectionError
|
ErrReplicationRemoteConnectionError
|
||||||
ErrBucketRemoteIdenticalToSource
|
ErrBucketRemoteIdenticalToSource
|
||||||
ErrBucketRemoteAlreadyExists
|
ErrBucketRemoteAlreadyExists
|
||||||
|
ErrBucketRemoteLabelInUse
|
||||||
ErrBucketRemoteArnTypeInvalid
|
ErrBucketRemoteArnTypeInvalid
|
||||||
ErrBucketRemoteArnInvalid
|
ErrBucketRemoteArnInvalid
|
||||||
ErrBucketRemoteRemoveDisallowed
|
ErrBucketRemoteRemoveDisallowed
|
||||||
ErrReplicationTargetNotVersionedError
|
ErrRemoteTargetNotVersionedError
|
||||||
ErrReplicationSourceNotVersionedError
|
ErrReplicationSourceNotVersionedError
|
||||||
ErrReplicationNeedsVersioningError
|
ErrReplicationNeedsVersioningError
|
||||||
ErrReplicationBucketNeedsVersioningError
|
ErrReplicationBucketNeedsVersioningError
|
||||||
@ -809,9 +810,9 @@ var errorCodes = errorCodeMap{
|
|||||||
Description: "The replication configuration was not found",
|
Description: "The replication configuration was not found",
|
||||||
HTTPStatusCode: http.StatusNotFound,
|
HTTPStatusCode: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
ErrReplicationDestinationNotFoundError: {
|
ErrRemoteDestinationNotFoundError: {
|
||||||
Code: "ReplicationDestinationNotFoundError",
|
Code: "RemoteDestinationNotFoundError",
|
||||||
Description: "The replication destination bucket does not exist",
|
Description: "The remote destination bucket does not exist",
|
||||||
HTTPStatusCode: http.StatusNotFound,
|
HTTPStatusCode: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
ErrReplicationDestinationMissingLock: {
|
ErrReplicationDestinationMissingLock: {
|
||||||
@ -819,9 +820,9 @@ var errorCodes = errorCodeMap{
|
|||||||
Description: "The replication destination bucket does not have object locking enabled",
|
Description: "The replication destination bucket does not have object locking enabled",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrReplicationTargetNotFoundError: {
|
ErrRemoteTargetNotFoundError: {
|
||||||
Code: "XMinioAdminReplicationTargetNotFoundError",
|
Code: "XMinioAdminRemoteTargetNotFoundError",
|
||||||
Description: "The replication target does not exist",
|
Description: "The remote target does not exist",
|
||||||
HTTPStatusCode: http.StatusNotFound,
|
HTTPStatusCode: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
ErrReplicationRemoteConnectionError: {
|
ErrReplicationRemoteConnectionError: {
|
||||||
@ -839,9 +840,14 @@ var errorCodes = errorCodeMap{
|
|||||||
Description: "The remote target already exists",
|
Description: "The remote target already exists",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
|
ErrBucketRemoteLabelInUse: {
|
||||||
|
Code: "XMinioAdminBucketRemoteLabelInUse",
|
||||||
|
Description: "The remote target with this label already exists",
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
},
|
||||||
ErrBucketRemoteRemoveDisallowed: {
|
ErrBucketRemoteRemoveDisallowed: {
|
||||||
Code: "XMinioAdminRemoteRemoveDisallowed",
|
Code: "XMinioAdminRemoteRemoveDisallowed",
|
||||||
Description: "Replication configuration exists with this ARN.",
|
Description: "This ARN is in use by an existing configuration",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrBucketRemoteArnTypeInvalid: {
|
ErrBucketRemoteArnTypeInvalid: {
|
||||||
@ -854,9 +860,9 @@ var errorCodes = errorCodeMap{
|
|||||||
Description: "The bucket remote ARN does not have correct format",
|
Description: "The bucket remote ARN does not have correct format",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrReplicationTargetNotVersionedError: {
|
ErrRemoteTargetNotVersionedError: {
|
||||||
Code: "ReplicationTargetNotVersionedError",
|
Code: "RemoteTargetNotVersionedError",
|
||||||
Description: "The replication target does not have versioning enabled",
|
Description: "The remote target does not have versioning enabled",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrReplicationSourceNotVersionedError: {
|
ErrReplicationSourceNotVersionedError: {
|
||||||
@ -1906,24 +1912,26 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
|
|||||||
apiErr = ErrAdminNoSuchQuotaConfiguration
|
apiErr = ErrAdminNoSuchQuotaConfiguration
|
||||||
case BucketReplicationConfigNotFound:
|
case BucketReplicationConfigNotFound:
|
||||||
apiErr = ErrReplicationConfigurationNotFoundError
|
apiErr = ErrReplicationConfigurationNotFoundError
|
||||||
case BucketReplicationDestinationNotFound:
|
case BucketRemoteDestinationNotFound:
|
||||||
apiErr = ErrReplicationDestinationNotFoundError
|
apiErr = ErrRemoteDestinationNotFoundError
|
||||||
case BucketReplicationDestinationMissingLock:
|
case BucketReplicationDestinationMissingLock:
|
||||||
apiErr = ErrReplicationDestinationMissingLock
|
apiErr = ErrReplicationDestinationMissingLock
|
||||||
case BucketRemoteTargetNotFound:
|
case BucketRemoteTargetNotFound:
|
||||||
apiErr = ErrReplicationTargetNotFoundError
|
apiErr = ErrRemoteTargetNotFoundError
|
||||||
case BucketRemoteConnectionErr:
|
case BucketRemoteConnectionErr:
|
||||||
apiErr = ErrReplicationRemoteConnectionError
|
apiErr = ErrReplicationRemoteConnectionError
|
||||||
case BucketRemoteAlreadyExists:
|
case BucketRemoteAlreadyExists:
|
||||||
apiErr = ErrBucketRemoteAlreadyExists
|
apiErr = ErrBucketRemoteAlreadyExists
|
||||||
|
case BucketRemoteLabelInUse:
|
||||||
|
apiErr = ErrBucketRemoteLabelInUse
|
||||||
case BucketRemoteArnTypeInvalid:
|
case BucketRemoteArnTypeInvalid:
|
||||||
apiErr = ErrBucketRemoteArnTypeInvalid
|
apiErr = ErrBucketRemoteArnTypeInvalid
|
||||||
case BucketRemoteArnInvalid:
|
case BucketRemoteArnInvalid:
|
||||||
apiErr = ErrBucketRemoteArnInvalid
|
apiErr = ErrBucketRemoteArnInvalid
|
||||||
case BucketRemoteRemoveDisallowed:
|
case BucketRemoteRemoveDisallowed:
|
||||||
apiErr = ErrBucketRemoteRemoveDisallowed
|
apiErr = ErrBucketRemoteRemoveDisallowed
|
||||||
case BucketReplicationTargetNotVersioned:
|
case BucketRemoteTargetNotVersioned:
|
||||||
apiErr = ErrReplicationTargetNotVersionedError
|
apiErr = ErrRemoteTargetNotVersionedError
|
||||||
case BucketReplicationSourceNotVersioned:
|
case BucketReplicationSourceNotVersioned:
|
||||||
apiErr = ErrReplicationSourceNotVersionedError
|
apiErr = ErrReplicationSourceNotVersionedError
|
||||||
case BucketQuotaExceeded:
|
case BucketQuotaExceeded:
|
||||||
|
@ -52,12 +52,12 @@ func getReplicationConfig(ctx context.Context, bucketName string) (rc *replicati
|
|||||||
// validateReplicationDestination returns error if replication destination bucket missing or not configured
|
// validateReplicationDestination returns error if replication destination bucket missing or not configured
|
||||||
// It also returns true if replication destination is same as this server.
|
// It also returns true if replication destination is same as this server.
|
||||||
func validateReplicationDestination(ctx context.Context, bucket string, rCfg *replication.Config) (bool, error) {
|
func validateReplicationDestination(ctx context.Context, bucket string, rCfg *replication.Config) (bool, error) {
|
||||||
clnt := globalBucketTargetSys.GetReplicationTargetClient(ctx, rCfg.RoleArn)
|
clnt := globalBucketTargetSys.GetRemoteTargetClient(ctx, rCfg.RoleArn)
|
||||||
if clnt == nil {
|
if clnt == nil {
|
||||||
return false, BucketRemoteTargetNotFound{Bucket: bucket}
|
return false, BucketRemoteTargetNotFound{Bucket: bucket}
|
||||||
}
|
}
|
||||||
if found, _ := clnt.BucketExists(ctx, rCfg.GetDestination().Bucket); !found {
|
if found, _ := clnt.BucketExists(ctx, rCfg.GetDestination().Bucket); !found {
|
||||||
return false, BucketReplicationDestinationNotFound{Bucket: rCfg.GetDestination().Bucket}
|
return false, BucketRemoteDestinationNotFound{Bucket: rCfg.GetDestination().Bucket}
|
||||||
}
|
}
|
||||||
if ret, err := globalBucketObjectLockSys.Get(bucket); err == nil {
|
if ret, err := globalBucketObjectLockSys.Get(bucket); err == nil {
|
||||||
if ret.LockEnabled {
|
if ret.LockEnabled {
|
||||||
@ -182,8 +182,7 @@ func replicateObject(ctx context.Context, objInfo ObjectInfo, objectAPI ObjectLa
|
|||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tgt := globalBucketTargetSys.GetRemoteTargetClient(ctx, cfg.RoleArn)
|
||||||
tgt := globalBucketTargetSys.GetReplicationTargetClient(ctx, cfg.RoleArn)
|
|
||||||
if tgt == nil {
|
if tgt == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,9 @@ func (sys *BucketTargetSys) SetTarget(ctx context.Context, bucket string, tgt *m
|
|||||||
return BucketRemoteConnectionErr{Bucket: tgt.TargetBucket}
|
return BucketRemoteConnectionErr{Bucket: tgt.TargetBucket}
|
||||||
}
|
}
|
||||||
if vcfg.Status != string(versioning.Enabled) {
|
if vcfg.Status != string(versioning.Enabled) {
|
||||||
return BucketReplicationTargetNotVersioned{Bucket: tgt.TargetBucket}
|
return BucketRemoteTargetNotVersioned{Bucket: tgt.TargetBucket}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sys.Lock()
|
sys.Lock()
|
||||||
defer sys.Unlock()
|
defer sys.Unlock()
|
||||||
|
|
||||||
@ -113,6 +112,9 @@ func (sys *BucketTargetSys) SetTarget(ctx context.Context, bucket string, tgt *m
|
|||||||
if t.Arn == tgt.Arn {
|
if t.Arn == tgt.Arn {
|
||||||
return BucketRemoteAlreadyExists{Bucket: t.TargetBucket}
|
return BucketRemoteAlreadyExists{Bucket: t.TargetBucket}
|
||||||
}
|
}
|
||||||
|
if t.Label == tgt.Label {
|
||||||
|
return BucketRemoteLabelInUse{Bucket: t.TargetBucket}
|
||||||
|
}
|
||||||
newtgts[idx] = *tgt
|
newtgts[idx] = *tgt
|
||||||
found = true
|
found = true
|
||||||
continue
|
continue
|
||||||
@ -173,8 +175,8 @@ func (sys *BucketTargetSys) RemoveTarget(ctx context.Context, bucket, arnStr str
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReplicationTargetClient returns minio-go client for replication target instance
|
// GetRemoteTargetClient returns minio-go client for replication target instance
|
||||||
func (sys *BucketTargetSys) GetReplicationTargetClient(ctx context.Context, arn string) *miniogo.Core {
|
func (sys *BucketTargetSys) GetRemoteTargetClient(ctx context.Context, arn string) *miniogo.Core {
|
||||||
sys.RLock()
|
sys.RLock()
|
||||||
defer sys.RUnlock()
|
defer sys.RUnlock()
|
||||||
return sys.arnRemotesMap[arn]
|
return sys.arnRemotesMap[arn]
|
||||||
|
@ -361,10 +361,10 @@ func (e BucketReplicationConfigNotFound) Error() string {
|
|||||||
return "The replication configuration was not found: " + e.Bucket
|
return "The replication configuration was not found: " + e.Bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketReplicationDestinationNotFound bucket does not exist.
|
// BucketRemoteDestinationNotFound bucket does not exist.
|
||||||
type BucketReplicationDestinationNotFound GenericError
|
type BucketRemoteDestinationNotFound GenericError
|
||||||
|
|
||||||
func (e BucketReplicationDestinationNotFound) Error() string {
|
func (e BucketRemoteDestinationNotFound) Error() string {
|
||||||
return "Destination bucket does not exist: " + e.Bucket
|
return "Destination bucket does not exist: " + e.Bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,6 +396,13 @@ func (e BucketRemoteAlreadyExists) Error() string {
|
|||||||
return "Remote already exists for this bucket: " + e.Bucket
|
return "Remote already exists for this bucket: " + e.Bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BucketRemoteLabelInUse remote already exists for this target label.
|
||||||
|
type BucketRemoteLabelInUse GenericError
|
||||||
|
|
||||||
|
func (e BucketRemoteLabelInUse) Error() string {
|
||||||
|
return "Remote with this label already exists for this bucket: " + e.Bucket
|
||||||
|
}
|
||||||
|
|
||||||
// BucketRemoteArnTypeInvalid arn type for remote is not valid.
|
// BucketRemoteArnTypeInvalid arn type for remote is not valid.
|
||||||
type BucketRemoteArnTypeInvalid GenericError
|
type BucketRemoteArnTypeInvalid GenericError
|
||||||
|
|
||||||
@ -417,11 +424,11 @@ func (e BucketRemoteRemoveDisallowed) Error() string {
|
|||||||
return "Replication configuration exists with this ARN:" + e.Bucket
|
return "Replication configuration exists with this ARN:" + e.Bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketReplicationTargetNotVersioned replication target does not have versioning enabled.
|
// BucketRemoteTargetNotVersioned remote target does not have versioning enabled.
|
||||||
type BucketReplicationTargetNotVersioned GenericError
|
type BucketRemoteTargetNotVersioned GenericError
|
||||||
|
|
||||||
func (e BucketReplicationTargetNotVersioned) Error() string {
|
func (e BucketRemoteTargetNotVersioned) Error() string {
|
||||||
return "Replication target does not have versioning enabled: " + e.Bucket
|
return "Remote target does not have versioning enabled: " + e.Bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketReplicationSourceNotVersioned replication source does not have versioning enabled.
|
// BucketReplicationSourceNotVersioned replication source does not have versioning enabled.
|
||||||
|
@ -94,6 +94,7 @@ type BucketTarget struct {
|
|||||||
Arn string `json:"arn,omitempty"`
|
Arn string `json:"arn,omitempty"`
|
||||||
Type ServiceType `json:"type"`
|
Type ServiceType `json:"type"`
|
||||||
Region string `json:"omitempty"`
|
Region string `json:"omitempty"`
|
||||||
|
Label string `json:"label,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone returns shallow clone of BucketTarget without secret key in credentials
|
// Clone returns shallow clone of BucketTarget without secret key in credentials
|
||||||
@ -109,6 +110,7 @@ func (t *BucketTarget) Clone() BucketTarget {
|
|||||||
Arn: t.Arn,
|
Arn: t.Arn,
|
||||||
Type: t.Type,
|
Type: t.Type,
|
||||||
Region: t.Region,
|
Region: t.Region,
|
||||||
|
Label: t.Label,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user