Skip to content

Commit

Permalink
Deprecated ibm_resource_access_tag and replaced it with ibm_iam_acces…
Browse files Browse the repository at this point in the history
…s_tag. Fixed 5566 too. (#5567)

* 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
  • Loading branch information
luiof authored Sep 11, 2024
1 parent 4712cab commit 52fab34
Show file tree
Hide file tree
Showing 9 changed files with 416 additions and 29 deletions.
4 changes: 4 additions & 0 deletions ibm/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,9 @@ func Provider() *schema.Provider {
"ibm_resource_tag": globaltagging.ResourceIBMResourceTag(),
"ibm_resource_access_tag": globaltagging.ResourceIBMResourceAccessTag(),

// Added for Iam Access Tag
"ibm_iam_access_tag": globaltagging.ResourceIBMIamAccessTag(),

// Atracker
"ibm_atracker_target": atracker.ResourceIBMAtrackerTarget(),
"ibm_atracker_route": atracker.ResourceIBMAtrackerRoute(),
Expand Down Expand Up @@ -1875,6 +1878,7 @@ func Validator() validate.ValidatorDict {
"ibm_is_virtual_endpoint_gateway": vpc.ResourceIBMISEndpointGatewayValidator(),
"ibm_resource_tag": globaltagging.ResourceIBMResourceTagValidator(),
"ibm_resource_access_tag": globaltagging.ResourceIBMResourceAccessTagValidator(),
"ibm_iam_access_tag": globaltagging.ResourceIBMIamAccessTagValidator(),
"ibm_satellite_location": satellite.ResourceIBMSatelliteLocationValidator(),
"ibm_satellite_cluster": satellite.ResourceIBMSatelliteClusterValidator(),
"ibm_pi_volume": power.ResourceIBMPIVolumeValidator(),
Expand Down
173 changes: 173 additions & 0 deletions ibm/service/globaltagging/resource_ibm_iam_access_tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Copyright IBM Corp. 2017, 2024 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0

package globaltagging

import (
"context"
"encoding/json"
"fmt"
"log"

"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate"
"github.com/IBM/platform-services-go-sdk/globaltaggingv1"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func ResourceIBMIamAccessTag() *schema.Resource {
return &schema.Resource{
CreateContext: resourceIBMIamAccessTagCreate,
ReadContext: resourceIBMIamAccessTagRead,
DeleteContext: resourceIBMIamAccessTagDelete,
Importer: &schema.ResourceImporter{},

Schema: map[string]*schema.Schema{

"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.InvokeValidator("ibm_iam_access_tag", "name"),
Set: flex.ResourceIBMVPCHash,
Description: "Name of the access tag",
},
tagType: {
Type: schema.TypeString,
Computed: true,
Description: "Type of the tag(access)",
},
},
}
}

func ResourceIBMIamAccessTagValidator() *validate.ResourceValidator {

validateSchema := make([]validate.ValidateSchema, 0)

validateSchema = append(validateSchema,
validate.ValidateSchema{
Identifier: "name",
ValidateFunctionIdentifier: validate.ValidateRegexpLen,
Type: validate.TypeString,
Required: true,
Regexp: `^([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-]):([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-])$`,
MinValueLength: 1,
MaxValueLength: 128})

ibmIamAccessTagValidator := validate.ResourceValidator{ResourceName: "ibm_iam_access_tag", Schema: validateSchema}
return &ibmIamAccessTagValidator
}

func resourceIBMIamAccessTagCreate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
tfErr := flex.TerraformErrorf(err, err.Error(), "ibm_iam_access_tag", "create")
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
return tfErr.GetDiag()
}

tagName := d.Get("name").(string)
add := make([]string, 0)
add = append(add, tagName)
accessTagType := "access"
createTagOptions := &globaltaggingv1.CreateTagOptions{
TagType: &accessTagType,
TagNames: add,
}
results, _, err := gtClient.CreateTagWithContext(context, createTagOptions)
if err != nil {
tfErr := flex.TerraformErrorf(err, err.Error(), "ibm_iam_access_tag", "create")
return tfErr.GetDiag()
}
if results != nil {
errMap := make([]globaltaggingv1.CreateTagResultsResultsItem, 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 diag.FromErr(fmt.Errorf("Error while creating access tag(%s) : %s", tagName, string(output)))
}
}

d.SetId(tagName)
d.Set(tagType, accessTagType)

return nil
}

func resourceIBMIamAccessTagRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
tagName := d.Id()
gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
tfErr := flex.TerraformErrorf(err, err.Error(), "ibm_iam_access_tag", "read")
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
return tfErr.GetDiag()
}
accessTagType := "access"
listTagsOptions := &globaltaggingv1.ListTagsOptions{
TagType: &accessTagType,
}
taggingResult, _, err := gtClient.ListTagsWithContext(context, listTagsOptions)
if err != nil {
tfErr := flex.TerraformErrorf(err, err.Error(), "ibm_iam_access_tag", "read")
return tfErr.GetDiag()
}

var taglist []string
for _, item := range taggingResult.Items {
taglist = append(taglist, *item.Name)
}
existingAccessTags := flex.NewStringSet(flex.ResourceIBMVPCHash, taglist)
if !existingAccessTags.Contains(tagName) {
d.SetId("")
return nil
}
d.Set("name", tagName)
d.Set(tagType, accessTagType)
return nil
}

func resourceIBMIamAccessTagDelete(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

gtClient, err := meta.(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
tfErr := flex.TerraformErrorf(err, err.Error(), "ibm_iam_access_tag", "update")
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
return tfErr.GetDiag()
}
tagName := d.Get("name").(string)
accessTagType := "access"

deleteTagOptions := &globaltaggingv1.DeleteTagOptions{
TagName: &tagName,
TagType: &accessTagType,
}

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))
}
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 diag.FromErr(fmt.Errorf("Error while deleting access tag(%s) : %s", tagName, string(output)))
}
}

d.SetId("")
return nil
}
147 changes: 147 additions & 0 deletions ibm/service/globaltagging/resource_ibm_iam_access_tag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright IBM Corp. 2017, 2024 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0

package globaltagging_test

import (
"fmt"
"regexp"
"strings"
"testing"

acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/IBM/platform-services-go-sdk/globaltaggingv1"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

const (
iamAccessTagRegex = "^([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-]):([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-])$"
)

func TestAccIamAccessTag_Basic(t *testing.T) {
name := fmt.Sprintf("tf%d:iam-access%d", acctest.RandIntRange(10, 100), acctest.RandIntRange(10, 100))

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
Steps: []resource.TestStep{

resource.TestStep{
Config: testAccCheckIamAccessTagCreate(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIamAccessTagExists("ibm_iam_access_tag.tag"),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "id", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "name", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "tag_type", "access"),
),
},
},
})
}
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,
Steps: []resource.TestStep{

resource.TestStep{
Config: testAccCheckIamAccessTagCreate(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIamAccessTagExists("ibm_iam_access_tag.tag"),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "id", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "name", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "tag_type", "access"),
),
},
resource.TestStep{
Config: testAccCheckIamAccessTagUsage(name, sshkeyname, publicKey),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIamAccessTagExists("ibm_iam_access_tag.tag"),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "id", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "name", name),
resource.TestCheckResourceAttr("ibm_iam_access_tag.tag", "tag_type", "access"),
testAccCheckResourceTagExists("ibm_resource_tag.tag"),
resource.TestCheckResourceAttr("ibm_resource_tag.tag", "tags.#", "1"),
resource.TestCheckResourceAttr("ibm_resource_tag.tag", "tags.0", name),
resource.TestCheckResourceAttr("ibm_resource_tag.tag", "tag_type", "access"),
),
},
},
})
}

func testAccCheckIamAccessTagExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
var tagName string
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

iamAccessTagRegex, err := regexp.Compile(iamAccessTagRegex)
if err != nil {
return err
}

if iamAccessTagRegex.MatchString(rs.Primary.ID) {
tagName = rs.Primary.ID
}

gtClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).GlobalTaggingAPIv1()
if err != nil {
return fmt.Errorf("Error getting global tagging client settings: %s", err)
}
accessTagType := "access"
listTagsOptions := &globaltaggingv1.ListTagsOptions{
TagType: &accessTagType,
}
taggingResult, _, err := gtClient.ListTags(listTagsOptions)
if err != nil {
return err
}

var taglist []string
for _, item := range taggingResult.Items {
taglist = append(taglist, *item.Name)
}
existingAccessTags := flex.NewStringSet(flex.ResourceIBMVPCHash, taglist)
if !existingAccessTags.Contains(tagName) {
return fmt.Errorf(
"Error on get of resource tags (%s) : %s", tagName, err)
}
return nil
}
}

func testAccCheckIamAccessTagCreate(name string) string {
return fmt.Sprintf(`
resource "ibm_iam_access_tag" "tag" {
name = "%s"
}
`, name)
}
func testAccCheckIamAccessTagUsage(name, sshkeyname, publicKey string) string {
return fmt.Sprintf(`
resource "ibm_iam_access_tag" "tag" {
name = "%s"
}
resource "ibm_is_ssh_key" "key" {
name = "%s"
public_key = "%s"
}
resource "ibm_resource_tag" "tag" {
resource_id = ibm_is_ssh_key.key.crn
tags = [ibm_iam_access_tag.tag.name]
tag_type = "access"
}
`, name, sshkeyname, publicKey)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func ResourceIBMResourceAccessTag() *schema.Resource {
Description: "Type of the tag(access)",
},
},
DeprecationMessage: "ibm_resource_access_tag has been deprecated. Use ibm_iam_access_tag instead.",
}
}

Expand Down
7 changes: 7 additions & 0 deletions ibm/service/globaltagging/resource_ibm_resource_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ func resourceIBMResourceTagDelete(d *schema.ResourceData, meta interface{}) erro
for i, v := range removeTags.List() {
remove[i] = fmt.Sprint(v)
}
var tType string
if v, ok := d.GetOk(tagType); ok && v != nil {
tType = v.(string)
} else {
tType = "user"
}

if len(remove) > 0 {
resources := []globaltaggingv1.Resource{}
Expand All @@ -313,6 +319,7 @@ func resourceIBMResourceTagDelete(d *schema.ResourceData, meta interface{}) erro
detachTagOptions := &globaltaggingv1.DetachTagOptions{
Resources: resources,
TagNames: remove,
TagType: &tType,
}

_, resp, err := gtClient.DetachTag(detachTagOptions)
Expand Down
Loading

0 comments on commit 52fab34

Please sign in to comment.