Skip to content

Commit

Permalink
CDPCP-12279 - Client Error should show failure reason
Browse files Browse the repository at this point in the history
  • Loading branch information
gregito committed Jul 23, 2024
1 parent 403b6d7 commit 5717c4c
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
- name: Go Coverage
uses: gwatts/go-coverage-action@v2.0.0
with:
coverage-threshold: 29.6
coverage-threshold: 32.0
cover-pkg: ./...
ignore-pattern: |
/cdp-sdk-go/
Expand Down
11 changes: 6 additions & 5 deletions resources/environments/resource_aws_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ import (
"context"
"time"

"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/cdp"
"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/client/operations"
environmentsmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/models"
"github.com/cloudera/terraform-provider-cdp/utils"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"

"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/cdp"
"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/client/operations"
environmentsmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/models"
"github.com/cloudera/terraform-provider-cdp/utils"
)

// Ensure the implementation satisfies the expected interfaces.
Expand Down Expand Up @@ -121,7 +122,7 @@ func (r *awsCredentialResource) Create(ctx context.Context, req resource.CreateR
responseOk, err := client.Operations.CreateAWSCredential(params)
if err != nil {
if envErr, ok := err.(*operations.CreateAWSCredentialDefault); ok {
if envErr.Code() == 403 {
if utils.IsRetryableError(envErr.Code()) {
return retry.RetryableError(err)
}
}
Expand Down
122 changes: 115 additions & 7 deletions utils/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,44 @@ import (
opdbmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/opdb/models"
)

const authFailMsg = "authentication failure, no access key provided or the key is no longer valid"

var NonRetryableErrorCodes = [...]int{403}

func IsNonRetryableError(code int) bool {
for _, nonRetryableCode := range NonRetryableErrorCodes {
if nonRetryableCode == code {
return true
}
}
return false
}

func IsRetryableError(code int) bool {
return !IsNonRetryableError(code)
}

type EnvironmentErrorPayload interface {
GetPayload() *environmentsmodels.Error
}

func decorateEnvironmentUnauthorizedErrorIfMessageNotExists(err *environmentsmodels.Error) *environmentsmodels.Error {
if err != nil && len(err.Message) == 0 {
return &environmentsmodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddEnvironmentDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(EnvironmentErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateEnvironmentUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -44,10 +74,23 @@ type IamErrorPayload interface {
GetPayload() *iammodels.Error
}

func decorateIamUnauthorizedErrorIfMessageNotExists(err *iammodels.Error) *iammodels.Error {
if err != nil && len(err.Message) == 0 {
return &iammodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddIamDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(IamErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateIamUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -60,10 +103,23 @@ type MlErrorPayload interface {
GetPayload() *mlmodels.Error
}

func decorateMlUnauthorizedErrorIfMessageNotExists(err *mlmodels.Error) *mlmodels.Error {
if err != nil && len(err.Message) == 0 {
return &mlmodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddMlDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(MlErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateMlUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -76,10 +132,23 @@ type DeErrorPayload interface {
GetPayload() *demodels.Error
}

func decorateDeUnauthorizedErrorIfMessageNotExists(err *demodels.Error) *demodels.Error {
if err != nil && len(err.Message) == 0 {
return &demodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddDeDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(DeErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateDeUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -92,10 +161,23 @@ type DatalakeErrorPayload interface {
GetPayload() *datalakemodels.Error
}

func decorateDatalakeUnauthorizedErrorIfMessageNotExists(err *datalakemodels.Error) *datalakemodels.Error {
if err != nil && len(err.Message) == 0 {
return &datalakemodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddDatalakeDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(DatalakeErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateDatalakeUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -108,10 +190,23 @@ type DatahubErrorPayload interface {
GetPayload() *datahubmodels.Error
}

func decorateDatahubUnauthorizedErrorIfMessageNotExists(err *datahubmodels.Error) *datahubmodels.Error {
if err != nil && len(err.Message) == 0 {
return &datahubmodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddDatahubDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(DatahubErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateDatahubUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand All @@ -124,10 +219,23 @@ type DatabaseErrorPayload interface {
GetPayload() *opdbmodels.Error
}

func decorateDatabaseUnauthorizedErrorIfMessageNotExists(err *opdbmodels.Error) *opdbmodels.Error {
if err != nil && len(err.Message) == 0 {
return &opdbmodels.Error{
Message: authFailMsg,
}
}
return err
}

func AddDatabaseDiagnosticsError(err error, diagnostics *diag.Diagnostics, errMsg string) {
msg := err.Error()
if d, ok := err.(DatabaseErrorPayload); ok && d.GetPayload() != nil {
msg = d.GetPayload().Message
if d.GetPayload().Code == "401" {
msg = decorateDatabaseUnauthorizedErrorIfMessageNotExists(d.GetPayload()).Message
} else {
msg = d.GetPayload().Message
}
}
caser := cases.Title(language.English)
diagnostics.AddError(
Expand Down
Loading

0 comments on commit 5717c4c

Please sign in to comment.