Skip to content

Commit

Permalink
Fix the 5635 - The ibm_resource_tag now checks the response in the ap…
Browse files Browse the repository at this point in the history
…i tags calls (IBM-Cloud#5641)

* Deprecated ibm_resource_access_tag in favor of ibm_iam_access_tag

* changes

* Fix

* Changed resource to speed up tests

* fix

* PR changes

* PR changes

* Added new context functions.
Now the code handles the error in the response on resource tags calls.

* Fixed 5635

* Fix

* Fixed

* Removed logs line
  • Loading branch information
luiof authored and Srikant Sahu committed Sep 24, 2024
1 parent a4c136f commit 5e66459
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 115 deletions.
111 changes: 88 additions & 23 deletions ibm/flex/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -2401,34 +2401,46 @@ func GetTags(d *schema.ResourceData, meta interface{}) error {
// }

func GetGlobalTagsUsingCRN(meta interface{}, resourceID, resourceType, tagType string) (*schema.Set, error) {
taggingResult, err := GetGlobalTagsUsingSearchAPI(meta, resourceID, resourceType, tagType)
if err != nil {
return nil, err
}
return taggingResult, nil
}

func GetTagsUsingResourceCRNFromTaggingApi(meta interface{}, resourceID, resourceType, tagType string) (*schema.Set, error) {
gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
return nil, fmt.Errorf("[ERROR] Error getting global tagging client settings: %s", err)
}
userDetails, err := meta.(conns.ClientSession).BluemixUserDetails()
if err != nil {
return nil, err
}
accountID := userDetails.UserAccount
ListTagsOptions := &globaltaggingv1.ListTagsOptions{}
if resourceID != "" {
ListTagsOptions.AttachedTo = &resourceID
}
ListTagsOptions.AttachedTo = &resourceID
if strings.HasPrefix(resourceType, "Softlayer_") {
ListTagsOptions.Providers = []string{"ims"}
}
if len(tagType) > 0 {
ListTagsOptions.TagType = PtrToString(tagType)

if tagType == "service" {
ListTagsOptions.AccountID = PtrToString(accountID)
}
}
taggingResult, err := GetGlobalTagsUsingSearchAPI(meta, resourceID, resourceType, tagType)
taggingResult, _, err := gtClient.ListTags(ListTagsOptions)
if err != nil {
return nil, err
}
return taggingResult, nil
var taglist []string
for _, item := range taggingResult.Items {
taglist = append(taglist, *item.Name)
}
return NewStringSet(ResourceIBMVPCHash, taglist), nil
}

func GetGlobalTagsUsingSearchAPI(meta interface{}, resourceID, resourceType, tagType string) (*schema.Set, error) {

gsClient, err := meta.(conns.ClientSession).GlobalSearchAPIV2()
if err != nil {
return nil, fmt.Errorf("[ERROR] Error getting global search client settings: %s", err)
Expand Down Expand Up @@ -2531,18 +2543,20 @@ func UpdateGlobalTagsUsingCRN(oldList, newList interface{}, meta interface{}, re
detachTagOptions.AccountID = PtrToString(acctID)
}
}

_, resp, err := gtClient.DetachTag(detachTagOptions)
results, fullResponse, err := gtClient.DetachTag(detachTagOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error detaching database tags %v: %s\n%s", remove, err, resp)
return fmt.Errorf("[ERROR] Error detaching tags calling api %v: %s\n%s", remove, err, fullResponse)
}
for _, v := range remove {
delTagOptions := &globaltaggingv1.DeleteTagOptions{
TagName: PtrToString(v),
if results != nil {
errMap := make([]globaltaggingv1.TagResultsItem, 0)
for _, res := range results.Results {
if res.IsError != nil && *res.IsError {
errMap = append(errMap, res)
}
}
_, resp, err := gtClient.DeleteTag(delTagOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error deleting database tag %v: %s\n%s", v, err, resp)
if len(errMap) > 0 {
output, _ := json.MarshalIndent(errMap, "", " ")
return fmt.Errorf("[ERROR] Error detaching tag in results %v: %s\n%s", remove, string(output), fullResponse)
}
}
}
Expand Down Expand Up @@ -2624,7 +2638,7 @@ func GetTagsUsingCRN(meta interface{}, resourceCRN string) (*schema.Set, error)
}

func UpdateTagsUsingCRN(oldList, newList interface{}, meta interface{}, resourceCRN string) error {
gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPI()
gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
return fmt.Errorf("[ERROR] Error getting global tagging client settings: %s", err)
}
Expand Down Expand Up @@ -2654,23 +2668,74 @@ func UpdateTagsUsingCRN(oldList, newList interface{}, meta interface{}, resource
add = append(add, envTags...)
}

resources := []globaltaggingv1.Resource{}
r := globaltaggingv1.Resource{ResourceID: &resourceCRN}
resources = append(resources, r)

if len(remove) > 0 {
_, err := gtClient.Tags().DetachTags(resourceCRN, remove)
detachTagOptions := &globaltaggingv1.DetachTagOptions{}
detachTagOptions.Resources = resources
detachTagOptions.TagNames = remove

results, fullResponse, err := gtClient.DetachTag(detachTagOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error detaching database tags %v: %s", remove, err)
return fmt.Errorf("[ERROR] Error detaching tags %v: %s", remove, err)
}
if results != nil {
errMap := make([]globaltaggingv1.TagResultsItem, 0)
for _, res := range results.Results {
if res.IsError != nil && *res.IsError {
errMap = append(errMap, res)
}
}
if len(errMap) > 0 {
output, _ := json.MarshalIndent(errMap, "", " ")
return fmt.Errorf("[ERROR] Error detaching tag %v: %s\n%s", remove, string(output), fullResponse)
}
}
for _, v := range remove {
_, err := gtClient.Tags().DeleteTag(v)
delTagOptions := &globaltaggingv1.DeleteTagOptions{
TagName: PtrToString(v),
}
results, fullResponse, err := gtClient.DeleteTag(delTagOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error deleting database tag %v: %s", v, err)
return fmt.Errorf("[ERROR] Error deleting tag %v: %s\n%s", v, err, fullResponse)
}

if results != nil {
errMap := make([]globaltaggingv1.DeleteTagResultsItem, 0)
for _, res := range results.Results {
if res.IsError != nil && *res.IsError {
errMap = append(errMap, res)
}
}
if len(errMap) > 0 {
output, _ := json.MarshalIndent(errMap, "", " ")
return fmt.Errorf("[ERROR] Error deleting tag %s: %s\n%s", v, string(output), fullResponse)
}
}
}
}

if len(add) > 0 {
_, err := gtClient.Tags().AttachTags(resourceCRN, add)
AttachTagOptions := &globaltaggingv1.AttachTagOptions{}
AttachTagOptions.Resources = resources
AttachTagOptions.TagNames = add
results, fullResponse, err := gtClient.AttachTag(AttachTagOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error updating database tags %v : %s", add, err)
return fmt.Errorf("[ERROR] Error updating tags %v : %s", add, err)
}
if results != nil {
errMap := make([]globaltaggingv1.TagResultsItem, 0)
for _, res := range results.Results {
if res.IsError != nil && *res.IsError {
errMap = append(errMap, res)
}
}
if len(errMap) > 0 {
output, _ := json.MarshalIndent(errMap, "", " ")
return fmt.Errorf("Error while updating tag: %s - Full response: %s", string(output), fullResponse)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions ibm/service/globaltagging/resource_ibm_iam_access_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func resourceIBMIamAccessTagDelete(context context.Context, d *schema.ResourceDa
results, resp, err := gtClient.DeleteTagWithContext(context, deleteTagOptions)

if err != nil {
return diag.FromErr(fmt.Errorf("Error while deleting access tag(%s) : %v\n%v", tagName, err, resp))
return diag.FromErr(fmt.Errorf("Error while deleting access tag calling api (%s) : %v\n%v", tagName, err, resp))
}
if results != nil {
errMap := make([]globaltaggingv1.DeleteTagResultsItem, 0)
Expand All @@ -164,7 +164,7 @@ func resourceIBMIamAccessTagDelete(context context.Context, d *schema.ResourceDa
}
if len(errMap) > 0 {
output, _ := json.MarshalIndent(errMap, "", " ")
return diag.FromErr(fmt.Errorf("Error while deleting access tag(%s) : %s", tagName, string(output)))
return diag.FromErr(fmt.Errorf("Error while deleting access tag in results (%s) : %s", tagName, string(output)))
}
}

Expand Down
24 changes: 12 additions & 12 deletions ibm/service/globaltagging/resource_ibm_iam_access_tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package globaltagging_test
import (
"fmt"
"regexp"
"strings"
"testing"

acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest"
Expand Down Expand Up @@ -44,10 +43,6 @@ func TestAccIamAccessTag_Basic(t *testing.T) {
}
func TestAccIamAccessTag_Usage(t *testing.T) {
name := fmt.Sprintf("tf%d:iam-access%d", acctest.RandIntRange(10, 100), acctest.RandIntRange(10, 100))
publicKey := strings.TrimSpace(`
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR
`)
sshkeyname := fmt.Sprintf("tfssh-createname-%d", acctest.RandIntRange(10, 100))
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Expand All @@ -63,7 +58,7 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVE
),
},
resource.TestStep{
Config: testAccCheckIamAccessTagUsage(name, sshkeyname, publicKey),
Config: testAccCheckIamAccessTagUsage(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIamAccessTagExists("ibm_iam_access_tag.tag"),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "id", name),
Expand Down Expand Up @@ -129,19 +124,24 @@ func testAccCheckIamAccessTagCreate(name string) string {
}
`, name)
}
func testAccCheckIamAccessTagUsage(name, sshkeyname, publicKey string) string {
func testAccCheckIamAccessTagUsage(name string) string {
resource_group_name := fmt.Sprintf("tf%d-iam-access%d", acctest.RandIntRange(10, 100), acctest.RandIntRange(10, 100))
return fmt.Sprintf(`
data "ibm_resource_group" "group" {
name = "Default"
}
resource "ibm_iam_access_tag" "tag" {
name = "%s"
}
resource "ibm_is_ssh_key" "key" {
name = "%s"
public_key = "%s"
resource "ibm_cd_toolchain" "cd_toolchain_instance" {
description = "Terraform test"
name = "%s-toolchain"
resource_group_id = data.ibm_resource_group.group.id
}
resource "ibm_resource_tag" "tag" {
resource_id = ibm_is_ssh_key.key.crn
resource_id = ibm_cd_toolchain.cd_toolchain_instance.crn
tags = [ibm_iam_access_tag.tag.name]
tag_type = "access"
}
`, name, sshkeyname, publicKey)
`, name, resource_group_name)
}
Loading

0 comments on commit 5e66459

Please sign in to comment.