diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 2406e629c..00762ef04 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -1956,6 +1956,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) { apiErr = ErrBackendDown case ObjectNameTooLong: apiErr = ErrKeyTooLongError + case dns.ErrInvalidBucketName: + apiErr = ErrInvalidBucketName default: var ie, iw int // This work-around is to handle the issue golang/go#30648 @@ -1992,6 +1994,12 @@ func toAPIError(ctx context.Context, err error) APIError { } var apiErr = errorCodes.ToAPIErr(toAPIErrorCode(ctx, err)) + e, ok := err.(dns.ErrInvalidBucketName) + if ok { + code := toAPIErrorCode(ctx, e) + apiErr = errorCodes.ToAPIErrWithErr(code, e) + } + if apiErr.Code == "InternalError" { // If we see an internal error try to interpret // any underlying errors if possible depending on diff --git a/cmd/config/dns/operator_dns.go b/cmd/config/dns/operator_dns.go index 3d323acea..cdea1da14 100644 --- a/cmd/config/dns/operator_dns.go +++ b/cmd/config/dns/operator_dns.go @@ -22,10 +22,12 @@ import ( "crypto/x509" "errors" "fmt" + "io" "net" "net/http" "net/url" "strconv" + "strings" "time" "github.com/dgrijalva/jwt-go" @@ -78,28 +80,39 @@ func (c *OperatorDNS) Put(bucket string) error { defer cancel() e, err := c.endpoint(bucket, false) if err != nil { - return err + return newError(bucket, err) } req, err := http.NewRequestWithContext(ctx, http.MethodPost, e, nil) if err != nil { - return err + return newError(bucket, err) } if err = c.addAuthHeader(req); err != nil { - return err + return newError(bucket, err) } resp, err := c.httpClient.Do(req) if err != nil { if derr := c.Delete(bucket); derr != nil { - return derr + return newError(bucket, derr) } } + var errorStringBuilder strings.Builder + io.Copy(&errorStringBuilder, io.LimitReader(resp.Body, resp.ContentLength)) xhttp.DrainBody(resp.Body) if resp.StatusCode != http.StatusOK { - return fmt.Errorf("request to create the service for bucket %s, failed with status %s", bucket, resp.Status) + errorString := errorStringBuilder.String() + return newError(bucket, fmt.Errorf("service create for bucket %s, failed with status %s, error %s", bucket, resp.Status, errorString)) } return nil } +func newError(bucket string, err error) error { + e := Error{bucket, err} + if strings.Contains(err.Error(), "invalid bucket name") { + return ErrInvalidBucketName(e) + } + return e +} + // Delete - Removes DNS entries added in Put(). func (c *OperatorDNS) Delete(bucket string) error { ctx, cancel := context.WithTimeout(context.Background(), defaultOperatorContextTimeout) diff --git a/cmd/config/dns/store.go b/cmd/config/dns/store.go index 98c044be5..1a097d1ae 100644 --- a/cmd/config/dns/store.go +++ b/cmd/config/dns/store.go @@ -16,6 +16,22 @@ package dns +// Error - DNS related errors error. +type Error struct { + Bucket string + Err error +} + +// ErrInvalidBucketName for buckets with invalid name +type ErrInvalidBucketName Error + +func (e ErrInvalidBucketName) Error() string { + return "invalid bucket name error: " + e.Err.Error() +} +func (e Error) Error() string { + return "dns related error: " + e.Err.Error() +} + // Store dns record store type Store interface { Put(bucket string) error