From 214250fd38dec634a8d4cd30a81ab84f6f502b22 Mon Sep 17 00:00:00 2001 From: SunithaGudisagar Date: Mon, 21 Oct 2024 14:07:08 +0530 Subject: [PATCH 1/2] enhancement(routine-table): added support for tags in routing table --- .../data_source_ibm_is_vpc_routing_table.go | 27 +++++ .../data_source_ibm_is_vpc_routing_tables.go | 29 +++++ .../vpc/resource_ibm_is_vpc_routing_table.go | 107 +++++++++++++++++- .../docs/d/is_vpc_routing_table.html.markdown | 10 +- .../d/is_vpc_routing_tables.html.markdown | 7 ++ .../docs/r/is_vpc_routing_table.html.markdown | 14 +++ 6 files changed, 192 insertions(+), 2 deletions(-) diff --git a/ibm/service/vpc/data_source_ibm_is_vpc_routing_table.go b/ibm/service/vpc/data_source_ibm_is_vpc_routing_table.go index d62e557870..31df0fb9e9 100644 --- a/ibm/service/vpc/data_source_ibm_is_vpc_routing_table.go +++ b/ibm/service/vpc/data_source_ibm_is_vpc_routing_table.go @@ -222,6 +222,19 @@ func DataSourceIBMIBMIsVPCRoutingTable() *schema.Resource { }, }, }, + rtTags: { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: flex.ResourceIBMVPCHash, + }, + rtAccessTags: { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: flex.ResourceIBMVPCHash, + Description: "List of access tags", + }, }, } } @@ -381,6 +394,20 @@ func dataSourceIBMIBMIsVPCRoutingTableRead(context context.Context, d *schema.Re return diag.FromErr(fmt.Errorf("[ERROR] Error setting resource group %s", err)) } + tags, err := flex.GetGlobalTagsUsingCRN(meta, *routingTable.CRN, "", rtUserTagType) + if err != nil { + log.Printf( + "An error occured during reading of routing table (%s) tags : %s", d.Id(), err) + } + d.Set(rtTags, tags) + + accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *routingTable.CRN, "", rtAccessTagType) + if err != nil { + log.Printf( + "An error occured during reading of routing table (%s) access tags: %s", d.Id(), err) + } + d.Set(rtAccessTags, accesstags) + return nil } diff --git a/ibm/service/vpc/data_source_ibm_is_vpc_routing_tables.go b/ibm/service/vpc/data_source_ibm_is_vpc_routing_tables.go index fd034a80ab..0ff98ec862 100644 --- a/ibm/service/vpc/data_source_ibm_is_vpc_routing_tables.go +++ b/ibm/service/vpc/data_source_ibm_is_vpc_routing_tables.go @@ -198,6 +198,21 @@ func DataSourceIBMISVPCRoutingTables() *schema.Resource { }, }, }, + + rtTags: { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: flex.ResourceIBMVPCHash, + }, + + rtAccessTags: { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: flex.ResourceIBMVPCHash, + Description: "List of access tags", + }, }, }, }, @@ -319,6 +334,20 @@ func dataSourceIBMISVPCRoutingTablesList(d *schema.ResourceData, meta interface{ } rtable[rtResourceGroup] = resourceGroupList + tags, err := flex.GetGlobalTagsUsingCRN(meta, *routingTable.CRN, "", rtUserTagType) + if err != nil { + log.Printf( + "An error occured during reading of routing table (%s) tags : %s", d.Id(), err) + } + rtable[rtTags] = tags + + accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *routingTable.CRN, "", rtAccessTagType) + if err != nil { + log.Printf( + "An error occured during reading of routing table (%s) access tags: %s", d.Id(), err) + } + rtable[rtAccessTags] = accesstags + vpcRoutingTables = append(vpcRoutingTables, rtable) } diff --git a/ibm/service/vpc/resource_ibm_is_vpc_routing_table.go b/ibm/service/vpc/resource_ibm_is_vpc_routing_table.go index 198627b358..392eb1c250 100644 --- a/ibm/service/vpc/resource_ibm_is_vpc_routing_table.go +++ b/ibm/service/vpc/resource_ibm_is_vpc_routing_table.go @@ -4,14 +4,18 @@ package vpc import ( + "context" "fmt" "log" + "os" "strings" "time" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate" "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/vpc-go-sdk/vpcv1" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -38,6 +42,10 @@ const ( rtResourceGroupHref = "href" rtResourceGroupId = "id" rtResourceGroupName = "name" + rtAccessTags = "access_tags" + rtAccessTagType = "access" + rtTags = "tags" + rtUserTagType = "user" ) func ResourceIBMISVPCRoutingTable() *schema.Resource { @@ -54,6 +62,12 @@ func ResourceIBMISVPCRoutingTable() *schema.Resource { Update: schema.DefaultTimeout(10 * time.Minute), Delete: schema.DefaultTimeout(10 * time.Minute), }, + CustomizeDiff: customdiff.All( + customdiff.Sequence( + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + return flex.ResourceValidateAccessTags(diff, v) + }), + ), Schema: map[string]*schema.Schema{ rtVpcID: { Type: schema.TypeString, @@ -190,6 +204,23 @@ func ResourceIBMISVPCRoutingTable() *schema.Resource { }, }, }, + rtTags: { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString, ValidateFunc: validate.InvokeValidator("ibm_is_vpc_routing_table", "tags")}, + Set: flex.ResourceIBMVPCHash, + Description: "List of tags", + }, + + rtAccessTags: { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString, ValidateFunc: validate.InvokeValidator("ibm_is_vpc_routing_table", "accesstag")}, + Set: flex.ResourceIBMVPCHash, + Description: "List of access management tags", + }, }, } } @@ -209,6 +240,26 @@ func ResourceIBMISVPCRoutingTableValidator() *validate.ResourceValidator { MinValueLength: 1, MaxValueLength: 63}) + validateSchema = append(validateSchema, validate.ValidateSchema{ + Identifier: "accesstag", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Optional: 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, + }) + + validateSchema = append(validateSchema, + validate.ValidateSchema{ + Identifier: "tags", + ValidateFunctionIdentifier: validate.ValidateRegexpLen, + Type: validate.TypeString, + Optional: true, + Regexp: `^[A-Za-z0-9:_ .-]+$`, + MinValueLength: 1, + MaxValueLength: 128}) + validateSchema = append(validateSchema, validate.ValidateSchema{ Identifier: rtAction, @@ -280,6 +331,25 @@ func resourceIBMISVPCRoutingTableCreate(d *schema.ResourceData, meta interface{} d.SetId(fmt.Sprintf("%s/%s", vpcID, *routeTable.ID)) + v := os.Getenv("IC_ENV_TAGS") + if _, ok := d.GetOk(rtTags); ok || v != "" { + oldList, newList := d.GetChange(rtTags) + err = flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, *routeTable.CRN, "", rtUserTagType) + if err != nil { + log.Printf( + "Error on create of resource routing table (%s) tags: %s", d.Id(), err) + } + } + + if _, ok := d.GetOk(rtAccessTags); ok { + oldList, newList := d.GetChange(rtAccessTags) + err = flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, *routeTable.CRN, "", rtAccessTags) + if err != nil { + log.Printf( + "Error on create of resource routing table (%s) access tags: %s", d.Id(), err) + } + } + return resourceIBMISVPCRoutingTableRead(d, meta) } @@ -348,6 +418,20 @@ func resourceIBMISVPCRoutingTableRead(d *schema.ResourceData, meta interface{}) } d.Set(rtResourceGroup, resourceGroupList) + tags, err := flex.GetGlobalTagsUsingCRN(meta, *routeTable.CRN, "", rtUserTagType) + if err != nil { + log.Printf( + "Error on get of resource routing table (%s) tags: %s", d.Id(), err) + } + d.Set(rtTags, tags) + + accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *routeTable.CRN, "", rtAccessTagType) + if err != nil { + log.Printf( + "Error on get of resource routing table (%s) access tags: %s", d.Id(), err) + } + d.Set(rtAccessTags, accesstags) + return nil } @@ -375,9 +459,30 @@ func resourceIBMISVPCRoutingTableUpdate(d *schema.ResourceData, meta interface{} //Etag idSett := strings.Split(d.Id(), "/") getVpcRoutingTableOptions := sess.NewGetVPCRoutingTableOptions(idSett[0], idSett[1]) - _, respGet, err := sess.GetVPCRoutingTable(getVpcRoutingTableOptions) + routingTableGet, respGet, err := sess.GetVPCRoutingTable(getVpcRoutingTableOptions) + if err != nil { + return fmt.Errorf("Error getting routing table : %s\n%s", err, respGet) + } eTag := respGet.Headers.Get("ETag") + if d.HasChange(rtAccessTags) { + oldList, newList := d.GetChange(rtAccessTags) + err = flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, *routingTableGet.CRN, "", rtAccessTagType) + if err != nil { + log.Printf( + "Error on update of resource routing table (%s) access tags: %s", d.Id(), err) + } + } + + if d.HasChange(rtTags) { + oldList, newList := d.GetChange(rtTags) + err = flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, *routingTableGet.CRN, "", rtUserTagType) + if err != nil { + log.Printf( + "Error on update of resource routing table (%s) tags: %s", d.Id(), err) + } + } + idSet := strings.Split(d.Id(), "/") updateVpcRoutingTableOptions := new(vpcv1.UpdateVPCRoutingTableOptions) updateVpcRoutingTableOptions.VPCID = &idSet[0] diff --git a/website/docs/d/is_vpc_routing_table.html.markdown b/website/docs/d/is_vpc_routing_table.html.markdown index f1e2630103..3a0c401a3a 100644 --- a/website/docs/d/is_vpc_routing_table.html.markdown +++ b/website/docs/d/is_vpc_routing_table.html.markdown @@ -49,6 +49,7 @@ Review the argument reference that you can specify for your data source. In addition to all argument references listed, you can access the following attribute references after your data source is created. +- `access_tags` - (List) Access management tags associated for the routing table. - `accept_routes_from` - (List) The filters specifying the resources that may create routes in this routing table.At present, only the `resource_type` filter is permitted, and only the `vpn_gateway` value is supported, but filter support is expected to expand in the future. Nested scheme for **accept_routes_from**: - `resource_type` - (String) The resource type. @@ -66,6 +67,12 @@ In addition to all argument references listed, you can access the following attr - Constraints: Allowable values are: `deleting`, `failed`, `pending`, `stable`, `suspended`, `updating`, `waiting`. - `name` - (String) The user-defined name for this routing table. - `resource_type` - (String) The resource type. +- `resource_group` - (List) The resource group for this routing table. + + Nested scheme for `resource_group`: + - `href` - (String) The URL for this resource group. + - `id` - (String) The unique identifier for this resource group. + - `name` - (String) The name for this resource group. - `route_direct_link_ingress` - (Boolean) Indicates whether this routing table is used to route traffic that originates from [Direct Link](https://cloud.ibm.com/docs/dl/) to this VPC.Incoming traffic will be routed according to the routing table with one exception: routes with an `action` of `deliver` are treated as `drop` unless the `next_hop` is an IP address within the VPC's address prefix ranges. Therefore, if an incoming packet matches a route with a `next_hop` of an internet-bound IP address or a VPN gateway connection, the packet will be dropped. - `route_internet_ingress` - (Boolean) Indicates whether this routing table is used to route traffic that originates from the internet.Incoming traffic will be routed according to the routing table with two exceptions:- Traffic destined for IP addresses associated with public gateways will not be subject to routes in this routing table.- Routes with an action of deliver are treated as drop unless the `next_hop` is an IP address bound to a network interface on a subnet in the route's `zone`. Therefore, if an incoming packet matches a route with a `next_hop` of an internet-bound IP address or a VPN gateway connection, the packet will be dropped. - `route_transit_gateway_ingress` - (Boolean) Indicates whether this routing table is used to route traffic that originates from from [Transit Gateway](https://cloud.ibm.com/cloud/transit-gateway/) to this VPC.Incoming traffic will be routed according to the routing table with one exception: routes with an `action` of `deliver` are treated as `drop` unless the `next_hop` is an IP address within the VPC's address prefix ranges. Therefore, if an incoming packet matches a route with a `next_hop` of an internet-bound IP address or a VPN gateway connection, the packet will be dropped. @@ -86,4 +93,5 @@ In addition to all argument references listed, you can access the following attr - `more_info` - (String) Link to documentation about deleted resources. - `href` - (String) The URL for this subnet. - `id` - (String) The unique identifier for this subnet. - - `name` - (String) The user-defined name for this subnet. \ No newline at end of file + - `name` - (String) The user-defined name for this subnet. +- `tags` - (String) Tags associated with the routing table. \ No newline at end of file diff --git a/website/docs/d/is_vpc_routing_tables.html.markdown b/website/docs/d/is_vpc_routing_tables.html.markdown index 76b3dbed46..7010850f54 100644 --- a/website/docs/d/is_vpc_routing_tables.html.markdown +++ b/website/docs/d/is_vpc_routing_tables.html.markdown @@ -45,6 +45,7 @@ In addition to the argument reference list, you can access the following attribu - `routing_tables` (List) List of all the routing tables in a VPC. Nested scheme for `routing_tables`: + - `access_tags` - (List) Access management tags associated for the routing table. - `accept_routes_from` - (List) The filters specifying the resources that may create routes in this routing table.At present, only the `resource_type` filter is permitted, and only the `vpn_gateway` value is supported, but filter support is expected to expand in the future. Nested scheme for **accept_routes_from**: - `resource_type` - (String) The resource type. @@ -60,6 +61,11 @@ In addition to the argument reference list, you can access the following attribu - `lifecycle_state` - (String) The lifecycle state of the routing table. - `name` - (String) The name for the default routing tables. - `resource_type` - (String) The type of resource referenced. + - `resource_group` - (List) The resource group for this routing table. + Nested scheme for `resource_group`: + - `href` - (String) The URL for this resource group. + - `id` - (String) The unique identifier for this resource group. + - `name` - (String) The name for this resource group. - `route_table` - (String) The unique ID for the routing table. - `route_direct_link_ingress` - (String) Indicates if the routing table is used to route traffic that originates from Direct Link to the VPC. - `route_internet_ingress` - (Boolean) Indicates whether this routing table is used to route traffic that originates from the internet. @@ -73,3 +79,4 @@ In addition to the argument reference list, you can access the following attribu Nested scheme for `subnets`: - `id` - (String) The unique ID of the subnet. - `name` - (String) The user-defined name of the subnet. + - `tags` - (String) Tags associated with the routing table. diff --git a/website/docs/r/is_vpc_routing_table.html.markdown b/website/docs/r/is_vpc_routing_table.html.markdown index 917c9f1173..7eddbe66fd 100644 --- a/website/docs/r/is_vpc_routing_table.html.markdown +++ b/website/docs/r/is_vpc_routing_table.html.markdown @@ -73,6 +73,13 @@ resource "ibm_is_vpc_routing_table" "example" { ## Argument reference Review the argument references that you can specify for your resource. +- `access_tags` - (Optional, List of Strings) A list of access management tags to attach to the routing table. + + ~> **Note:** + **•** You can attach only those access tags that already exists.
+ **•** For more information, about creating access tags, see [working with tags](https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#create-access-console).
+ **•** You must have the access listed in the [Granting users access to tag resources](https://cloud.ibm.com/docs/account?topic=account-access) for `access_tags`
+ **•** `access_tags` must be in the format `key:value`. - `advertise_routes_to` - (Optional, List) The ingress sources to advertise routes to. Routes in the table with `advertise` enabled will be advertised to these sources. ->**Options** An ingress source that routes can be advertised to:
@@ -85,6 +92,7 @@ Review the argument references that you can specify for your resource. - `route_internet_ingress` - (Optional, Bool) If set to **true**, this routing table will be used to route traffic that originates from the internet. For this to succeed, the VPC must not already have a routing table with this property set to **true**. - `route_transit_gateway_ingress` - (Optional, Bool) If set to **true**, the routing table is used to route traffic that originates from Transit Gateway to the VPC. To succeed, the VPC must not already have a routing table with the property set to **true**. - `route_vpc_zone_ingress` - (Optional, Bool) If set to true, the routing table is used to route traffic that originates from subnets in other zones in the VPC. To succeed, the VPC must not already have a routing table with the property set to **true**. +- `tags` - (Optional, Array of Strings) Enter any tags that you want to associate with your routing table. Tags might help you find your routing table more easily after it is created. Separate multiple tags with a comma (`,`). - `vpc` - (Required, Forces new resource, String) The VPC ID. ## Attribute reference @@ -96,6 +104,12 @@ In addition to all argument reference list, you can access the following attribu - `is_default` - (String) Indicates the default routing table for this VPC. - `lifecycle_state` - (String) The lifecycle state of the routing table. - `resource_type` - (String) The resource type. +- `resource_group` - (List) The resource group for this routing table. + + Nested scheme for `resource_group`: + - `href` - (String) The URL for this resource group. + - `id` - (String) The unique identifier for this resource group. + - `name` - (String) The name for this resource group. - `routing_table` - (String) The unique routing table identifier. - `routes` - (List) The routes for the routing table. From d3f8b7845125331a088c566c726a6157a4f9ba8e Mon Sep 17 00:00:00 2001 From: SunithaGudisagar Date: Wed, 23 Oct 2024 13:00:44 +0530 Subject: [PATCH 2/2] Update --- website/docs/d/is_vpc_routing_table.html.markdown | 2 +- website/docs/d/is_vpc_routing_tables.html.markdown | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/d/is_vpc_routing_table.html.markdown b/website/docs/d/is_vpc_routing_table.html.markdown index 3a0c401a3a..b533a0b9e5 100644 --- a/website/docs/d/is_vpc_routing_table.html.markdown +++ b/website/docs/d/is_vpc_routing_table.html.markdown @@ -94,4 +94,4 @@ In addition to all argument references listed, you can access the following attr - `href` - (String) The URL for this subnet. - `id` - (String) The unique identifier for this subnet. - `name` - (String) The user-defined name for this subnet. -- `tags` - (String) Tags associated with the routing table. \ No newline at end of file +- `tags` - (List) Tags associated with the routing table. \ No newline at end of file diff --git a/website/docs/d/is_vpc_routing_tables.html.markdown b/website/docs/d/is_vpc_routing_tables.html.markdown index 7010850f54..d0dd13dfc8 100644 --- a/website/docs/d/is_vpc_routing_tables.html.markdown +++ b/website/docs/d/is_vpc_routing_tables.html.markdown @@ -79,4 +79,4 @@ In addition to the argument reference list, you can access the following attribu Nested scheme for `subnets`: - `id` - (String) The unique ID of the subnet. - `name` - (String) The user-defined name of the subnet. - - `tags` - (String) Tags associated with the routing table. + - `tags` - (List) Tags associated with the routing table.