Skip to content

Commit f79697e

Browse files
authored
[bugfix] Fix issue when APIC return error 'cannot be deleted.' with wrong error code (DCNE-380) (#1354)
1 parent a1c2b14 commit f79697e

File tree

3 files changed

+74
-22
lines changed

3 files changed

+74
-22
lines changed

internal/provider/data_source_aci_rest_managed_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
func TestAccDataSourceAciRestManaged_tenant(t *testing.T) {
1111
resource.Test(t, resource.TestCase{
12-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
12+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
1313
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
1414
Steps: []resource.TestStep{
1515
{

internal/provider/resource_aci_rest_managed_test.go

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func TestAccAciRestManaged_tenant(t *testing.T) {
1313
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
1414

1515
resource.Test(t, resource.TestCase{
16-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
16+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
1717
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
1818
Steps: []resource.TestStep{
1919
{
@@ -52,7 +52,7 @@ func TestAccAciRestManaged_tenant(t *testing.T) {
5252

5353
func TestAccAciRestManaged_connPref(t *testing.T) {
5454
resource.Test(t, resource.TestCase{
55-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
55+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
5656
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
5757
Steps: []resource.TestStep{
5858
{
@@ -79,7 +79,7 @@ func TestAccAciRestManaged_connPref(t *testing.T) {
7979

8080
func TestAccAciRestManaged_escapeHtml(t *testing.T) {
8181
resource.Test(t, resource.TestCase{
82-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
82+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
8383
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
8484
Steps: []resource.TestStep{
8585
{
@@ -98,7 +98,7 @@ func TestAccAciRestManaged_escapeHtml(t *testing.T) {
9898

9999
func TestAccAciRestManaged_escapeHtmlTrue(t *testing.T) {
100100
resource.Test(t, resource.TestCase{
101-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
101+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
102102
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
103103
Steps: []resource.TestStep{
104104
{
@@ -118,7 +118,7 @@ func TestAccAciRestManaged_escapeHtmlTrue(t *testing.T) {
118118

119119
func TestAccAciRestManaged_noContent(t *testing.T) {
120120
resource.Test(t, resource.TestCase{
121-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
121+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
122122
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
123123
Steps: []resource.TestStep{
124124
{
@@ -136,7 +136,7 @@ func TestAccAciRestManaged_tenantVrf(t *testing.T) {
136136
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
137137

138138
resource.Test(t, resource.TestCase{
139-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
139+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
140140
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
141141
Steps: []resource.TestStep{
142142
{
@@ -159,7 +159,7 @@ func TestAccAciRestManaged_import(t *testing.T) {
159159
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
160160

161161
resource.Test(t, resource.TestCase{
162-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
162+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
163163
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
164164
Steps: []resource.TestStep{
165165
{
@@ -339,7 +339,7 @@ func TestAccAciRestManaged_importWithIpv6(t *testing.T) {
339339
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
340340

341341
resource.Test(t, resource.TestCase{
342-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
342+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
343343
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
344344
Steps: []resource.TestStep{
345345
{
@@ -427,7 +427,7 @@ func TestAccAciRestManaged_importWithBracket(t *testing.T) {
427427
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
428428

429429
resource.Test(t, resource.TestCase{
430-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
430+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
431431
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
432432
Steps: []resource.TestStep{
433433
{
@@ -504,7 +504,7 @@ func TestAccAciRestManaged_tagTag(t *testing.T) {
504504
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
505505

506506
resource.Test(t, resource.TestCase{
507-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
507+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
508508
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
509509
Steps: []resource.TestStep{
510510
{
@@ -527,7 +527,7 @@ func TestAccAciRestManaged_tenantChildren(t *testing.T) {
527527
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
528528

529529
resource.Test(t, resource.TestCase{
530-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
530+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
531531
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
532532
Steps: []resource.TestStep{
533533
{
@@ -568,7 +568,7 @@ func TestAccAciRestManaged_globalAllowExistingOnCreate(t *testing.T) {
568568
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
569569

570570
resource.Test(t, resource.TestCase{
571-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
571+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
572572
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
573573
Steps: []resource.TestStep{
574574
{
@@ -584,7 +584,7 @@ func TestAccAciRestManaged_globalAllowExistingOnCreate(t *testing.T) {
584584

585585
setEnvVariable(t, "ACI_ALLOW_EXISTING_ON_CREATE", "false")
586586
resource.Test(t, resource.TestCase{
587-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
587+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
588588
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
589589
Steps: []resource.TestStep{
590590
{
@@ -596,7 +596,7 @@ func TestAccAciRestManaged_globalAllowExistingOnCreate(t *testing.T) {
596596

597597
setEnvVariable(t, "ACI_ALLOW_EXISTING_ON_CREATE", "true")
598598
resource.Test(t, resource.TestCase{
599-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
599+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
600600
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
601601
Steps: []resource.TestStep{
602602
{
@@ -615,7 +615,7 @@ func TestAccAciRestManaged_globalAnnotation(t *testing.T) {
615615
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
616616

617617
resource.Test(t, resource.TestCase{
618-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
618+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
619619
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
620620
Steps: []resource.TestStep{
621621
{
@@ -633,7 +633,7 @@ func TestAccAciRestManaged_globalAnnotation(t *testing.T) {
633633

634634
setEnvVariable(t, "ACI_ANNOTATION", "orchestrator:from_env")
635635
resource.Test(t, resource.TestCase{
636-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
636+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
637637
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
638638
Steps: []resource.TestStep{
639639
{
@@ -698,7 +698,7 @@ func TestAccAciRestManaged_globalAnnotation(t *testing.T) {
698698
})
699699
setEnvVariable(t, "ACI_ANNOTATION", "")
700700
resource.Test(t, resource.TestCase{
701-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
701+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
702702
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
703703
Steps: []resource.TestStep{
704704
{
@@ -718,7 +718,7 @@ func TestAccAciRestManaged_globalAnnotation(t *testing.T) {
718718

719719
func TestAccAciRestManaged_undeletableClass(t *testing.T) {
720720
resource.Test(t, resource.TestCase{
721-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
721+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
722722
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
723723
Steps: []resource.TestStep{
724724
{
@@ -752,7 +752,7 @@ func TestAccAciRestManaged_explicitNull(t *testing.T) {
752752
name := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
753753

754754
resource.Test(t, resource.TestCase{
755-
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)") },
755+
PreCheck: func() { testAccPreCheck(t, "both", "5.2(7g)-") },
756756
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
757757
Steps: []resource.TestStep{
758758
{
@@ -804,6 +804,35 @@ func TestAccAciRestManaged_explicitNull(t *testing.T) {
804804

805805
}
806806

807+
func TestAccAciRestManaged_undeletableObject(t *testing.T) {
808+
resource.Test(t, resource.TestCase{
809+
PreCheck: func() { testAccPreCheck(t, "both", "2.0(1m)-") },
810+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
811+
Steps: []resource.TestStep{
812+
{
813+
Config: testAccAciRestManagedConfig_undeletableObject(),
814+
ExpectNonEmptyPlan: false,
815+
Check: resource.ComposeTestCheckFunc(
816+
// Validate the attributes for fvFabricExtConnP
817+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "dn", "uni/tn-infra/fabricExtConnP-1"),
818+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "class_name", "fvFabricExtConnP"),
819+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "content.id", "1"),
820+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "content.name", "IPN"),
821+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "content.rt", "extended:as2-nn4:5:16"),
822+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "content.siteId", "1"),
823+
resource.TestCheckResourceAttr("aci_rest_managed.fvFabricExtConnP", "content.%", "4"),
824+
825+
// Validate the attributes for fvPeeringP
826+
resource.TestCheckResourceAttr("aci_rest_managed.fvPeeringP", "dn", "uni/tn-infra/fabricExtConnP-1/peeringP"),
827+
resource.TestCheckResourceAttr("aci_rest_managed.fvPeeringP", "class_name", "fvPeeringP"),
828+
resource.TestCheckResourceAttr("aci_rest_managed.fvPeeringP", "content.type", "automatic_with_rr"),
829+
resource.TestCheckResourceAttr("aci_rest_managed.fvPeeringP", "content.%", "1"),
830+
),
831+
},
832+
},
833+
})
834+
}
835+
807836
func testAccAciRestManagedConfig_tenant(name string, description string) string {
808837
return fmt.Sprintf(`
809838
resource "aci_rest_managed" "fvTenant" {
@@ -1229,3 +1258,26 @@ func testAccAciRestManagedConfig_escapeHtmlTrue() string {
12291258
}
12301259
`
12311260
}
1261+
1262+
func testAccAciRestManagedConfig_undeletableObject() string {
1263+
return `
1264+
resource "aci_rest_managed" "fvFabricExtConnP" {
1265+
dn = "uni/tn-infra/fabricExtConnP-1"
1266+
class_name = "fvFabricExtConnP"
1267+
content = {
1268+
id = "1"
1269+
name = "IPN"
1270+
rt = "extended:as2-nn4:5:16"
1271+
siteId = "1"
1272+
}
1273+
}
1274+
resource "aci_rest_managed" "fvPeeringP" {
1275+
dn = "${aci_rest_managed.fvFabricExtConnP.dn}/peeringP"
1276+
class_name = "fvPeeringP"
1277+
escape_html = false
1278+
content = {
1279+
type = "automatic_with_rr"
1280+
}
1281+
}
1282+
`
1283+
}

internal/provider/utils.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ func DoRestRequestEscapeHtml(ctx context.Context, diags *diag.Diagnostics, aciCl
108108
if restResponse != nil && cont.Data() != nil && restResponse.StatusCode != 200 {
109109
errCode := models.StripQuotes(models.StripSquareBrackets(cont.Search("imdata", "error", "attributes", "code").String()))
110110
errText := models.StripQuotes(models.StripSquareBrackets(cont.Search("imdata", "error", "attributes", "text").String()))
111-
// Ignore errors of type "Cannot create object", "Cannot delete object", "Request in progress" and error text containing "can not be deleted." when the error code is 120
112-
if errCode == "103" || errCode == "107" || errCode == "202" || (errCode == "120" && strings.HasSuffix(errText, "can not be deleted.")) {
111+
// Ignore errors of type "Cannot create object", "Cannot delete object", "Request in progress", error text containing "can not be deleted." when the error code is 120 and error text containing "cannot be deleted." when the error code is 1
112+
if errCode == "103" || errCode == "107" || errCode == "202" || (errCode == "120" && strings.HasSuffix(errText, "can not be deleted.")) || (errCode == "1" && strings.HasSuffix(errText, "cannot be deleted.")) {
113113
tflog.Debug(ctx, fmt.Sprintf("Exiting from error: Code: %s, Message: %s", errCode, errText))
114114
return nil
115115
} else if (errText == "" && errCode == "403") || errCode == "401" {

0 commit comments

Comments
 (0)