Skip to content

Commit

Permalink
Feature(vpc Advertise routes): Support route advertising in vpc (#5005)
Browse files Browse the repository at this point in the history
* added advertised route support

* doc updates for routing table/s

* Change advertise_routes_to from List to HashSet and modify create, update and read methods accordingly

* Add latest generated go sdk

* update with latest sdk

* add beta maturity to sdk

* corrected docs as per review comment

* updated go mod

* Update resource_ibm_is_bare_metal_server.go

* rm common

---------

Co-authored-by: Bhavesh Shrivastav <[email protected]>
Co-authored-by: Ujjwal Kumar <[email protected]>
  • Loading branch information
3 people authored Dec 28, 2023
1 parent fa9b52f commit f2f674e
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 14 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ require (
github.com/IBM/schematics-go-sdk v0.2.2
github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2
github.com/IBM/vpc-beta-go-sdk v0.6.0
github.com/IBM/vpc-go-sdk v0.46.0
github.com/IBM/vpc-go-sdk v0.47.0
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
github.com/akamai/AkamaiOPEN-edgegrid-golang/v5 v5.0.0
Expand Down Expand Up @@ -235,6 +235,7 @@ replace github.com/softlayer/softlayer-go v1.0.3 => github.com/IBM-Cloud/softlay

replace github.com/dgrijalva/jwt-go v3.2.0+incompatible => github.com/golang-jwt/jwt v3.2.1+incompatible

// add sdk changes.
replace github.com/portworx/sched-ops v0.0.0-20200831185134-3e8010dc7056 => github.com/portworx/sched-ops v0.20.4-openstorage-rc3 // required by rook v1.7

exclude (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2 h1:+Svh1OmoFxMBnZQSOUtp2UUzrOGFs
github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2/go.mod h1:WII+LS4VkQYykmq65NWSuPb5xGNvsqkcK1aCWZoU2x4=
github.com/IBM/vpc-beta-go-sdk v0.6.0 h1:wfM3AcW3zOM3xsRtZ+EA6+sESlGUjQ6Yf4n5QQyz4uc=
github.com/IBM/vpc-beta-go-sdk v0.6.0/go.mod h1:fzHDAQIqH/5yJmYsKodKHLcqxMDT+yfH6vZjdiw8CQA=
github.com/IBM/vpc-go-sdk v0.46.0 h1:OwXH3oaYgYmzt559n77AteSpNsW4H1PoeHcR4EOolzk=
github.com/IBM/vpc-go-sdk v0.46.0/go.mod h1:4Hs5d/aClmsxAzwDQkwG+ri0vW2ykPJdpM6hDLRwKcA=
github.com/IBM/vpc-go-sdk v0.47.0 h1:2Qcjd4zQQRYjz+y4ZMDP6+aWGifyXCZ9uMmlpW7p9To=
github.com/IBM/vpc-go-sdk v0.47.0/go.mod h1:4Hs5d/aClmsxAzwDQkwG+ri0vW2ykPJdpM6hDLRwKcA=
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0=
Expand Down
11 changes: 11 additions & 0 deletions ibm/service/vpc/data_source_ibm_is_vpc_routing_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func DataSourceIBMIBMIsVPCRoutingTable() *schema.Resource {
Description: "The routing table identifier.",
},

"advertise_routes_to": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "The ingress sources to advertise routes to. Routes in the table with `advertise` enabled will be advertised to these sources.The enumerated values for this property are expected to expand in the future. When processing this property, check for and log unknown values. Optionally halt processing and surface the error, or bypass the resource on which the unexpected property value was encountered.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
rtCreateAt: &schema.Schema{
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -297,6 +305,9 @@ func dataSourceIBMIBMIsVPCRoutingTableRead(context context.Context, d *schema.Re
return diag.FromErr(fmt.Errorf("[ERROR] Error setting route_vpc_zone_ingress: %s", err))
}

if err = d.Set("advertise_routes_to", routingTable.AdvertiseRoutesTo); err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error setting value of advertise_routes_to: %s", err))
}
routes := []map[string]interface{}{}
if routingTable.Routes != nil {
for _, modelItem := range routingTable.Routes {
Expand Down
9 changes: 9 additions & 0 deletions ibm/service/vpc/data_source_ibm_is_vpc_routing_table_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ func DataSourceIBMIBMIsVPCRoutingTableRoute() *schema.Resource {
Computed: true,
Description: "The action to perform with a packet matching the route:- `delegate`: delegate to the system's built-in routes- `delegate_vpc`: delegate to the system's built-in routes, ignoring Internet-bound routes- `deliver`: deliver the packet to the specified `next_hop`- `drop`: drop the packet.",
},
"advertise": &schema.Schema{
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether this route will be advertised to the ingress sources specified by the `advertise_routes_to` routing table property.",
},
rtCreateAt: &schema.Schema{
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -271,6 +276,10 @@ func dataSourceIBMIBMIsVPCRoutingTableRouteRead(context context.Context, d *sche
return diag.FromErr(fmt.Errorf("[ERROR] Error setting action: %s", err))
}

if err = d.Set("advertise", route.Advertise); err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error setting advertise: %s", err))
}

if err = d.Set(rtCreateAt, flex.DateTimeToString(route.CreatedAt)); err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error setting created_at: %s", err))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ func DataSourceIBMISVPCRoutingTableRoutes() *schema.Resource {
Computed: true,
Description: "Routing Table Route Action",
},
"advertise": &schema.Schema{
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether this route will be advertised to the ingress sources specified by the `advertise_routes_to` routing table property.",
},
isRoutingTableRouteDestination: {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -216,6 +221,9 @@ func dataSourceIBMISVPCRoutingTableRoutesList(d *schema.ResourceData, meta inter
if instance.LifecycleState != nil {
route[isRoutingTableRouteLifecycleState] = *instance.LifecycleState
}
if instance.Advertise != nil {
route["advertise"] = *instance.Advertise
}
if instance.Destination != nil {
route[isRoutingTableRouteDestination] = *instance.Destination
}
Expand Down
11 changes: 11 additions & 0 deletions ibm/service/vpc/data_source_ibm_is_vpc_routing_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ func DataSourceIBMISVPCRoutingTables() *schema.Resource {
Computed: true,
Description: "Routing Table ID",
},
"advertise_routes_to": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "The ingress sources to advertise routes to. Routes in the table with `advertise` enabled will be advertised to these sources.The enumerated values for this property are expected to expand in the future. When processing this property, check for and log unknown values. Optionally halt processing and surface the error, or bypass the resource on which the unexpected property value was encountered.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
isRoutingTableHref: {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -241,6 +249,9 @@ func dataSourceIBMISVPCRoutingTablesList(d *schema.ResourceData, meta interface{
if routingTable.RouteVPCZoneIngress != nil {
rtable[isRoutingTableVPCZoneIngress] = *routingTable.RouteVPCZoneIngress
}
if routingTable.AdvertiseRoutesTo != nil {
rtable["advertise_routes_to"] = routingTable.AdvertiseRoutesTo
}
if routingTable.IsDefault != nil {
rtable[isRoutingTableDefault] = *routingTable.IsDefault
}
Expand Down
11 changes: 6 additions & 5 deletions ibm/service/vpc/resource_ibm_is_bare_metal_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,8 @@ func resourceIBMISBareMetalServerCreate(context context.Context, d *schema.Resou
if err != nil {
return diag.FromErr(err)
}
options := &vpcv1.CreateBareMetalServerOptions{}
createbmsoptions := &vpcv1.CreateBareMetalServerOptions{}
options := &vpcv1.BareMetalServerPrototype{}
var imageStr string
if image, ok := d.GetOk(isBareMetalServerImage); ok {
imageStr = image.(string)
Expand All @@ -705,7 +706,7 @@ func resourceIBMISBareMetalServerCreate(context context.Context, d *schema.Resou
// enable secure boot

if _, ok := d.GetOkExists(isBareMetalServerEnableSecureBoot); ok {
options.SetEnableSecureBoot(d.Get(isBareMetalServerEnableSecureBoot).(bool))
options.EnableSecureBoot = core.BoolPtr(d.Get(isBareMetalServerEnableSecureBoot).(bool))
}

// trusted_platform_module
Expand All @@ -715,7 +716,7 @@ func resourceIBMISBareMetalServerCreate(context context.Context, d *schema.Resou
if err != nil {
return diag.FromErr(err)
}
options.SetTrustedPlatformModule(trustedPlatformModuleModel)
options.TrustedPlatformModule = trustedPlatformModuleModel
}

keySet := d.Get(isBareMetalServerKeys).(*schema.Set)
Expand Down Expand Up @@ -1300,8 +1301,8 @@ func resourceIBMISBareMetalServerCreate(context context.Context, d *schema.Resou
ID: &vpc,
}
}

bms, response, err := sess.CreateBareMetalServerWithContext(context, options)
createbmsoptions.BareMetalServerPrototype = options
bms, response, err := sess.CreateBareMetalServerWithContext(context, createbmsoptions)
if err != nil {
return diag.FromErr(fmt.Errorf("[DEBUG] Create bare metal server err %s\n%s", err, response))
}
Expand Down
37 changes: 37 additions & 0 deletions ibm/service/vpc/resource_ibm_is_vpc_routing_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ func ResourceIBMISVPCRoutingTable() *schema.Resource {
Set: schema.HashString,
Description: "The filters specifying the resources that may create routes in this routing table, The resource type: vpn_gateway or vpn_server",
},
"advertise_routes_to": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Computed: true,
Set: schema.HashString,
Description: "The ingress sources to advertise routes to. Routes in the table with `advertise` enabled will be advertised to these sources.",
Elem: &schema.Schema{Type: schema.TypeString},
},
rtRouteDirectLinkIngress: {
Type: schema.TypeBool,
ForceNew: false,
Expand Down Expand Up @@ -209,6 +217,15 @@ func resourceIBMISVPCRoutingTableCreate(d *schema.ResourceData, meta interface{}
}
createVpcRoutingTableOptions.AcceptRoutesFrom = aroutes
}
if _, ok := d.GetOk("advertise_routes_to"); ok {
var advertiseRoutesToList []string
advertiseRoutesTo := d.Get("advertise_routes_to").(*schema.Set)

for _, val := range advertiseRoutesTo.List() {
advertiseRoutesToList = append(advertiseRoutesToList, val.(string))
}
createVpcRoutingTableOptions.AdvertiseRoutesTo = advertiseRoutesToList
}

if _, ok := d.GetOk(rtRouteInternetIngress); ok {
rtRouteInternetIngress := d.Get(rtRouteInternetIngress).(bool)
Expand Down Expand Up @@ -263,12 +280,22 @@ func resourceIBMISVPCRoutingTableRead(d *schema.ResourceData, meta interface{})
d.Set(rtRouteVPCZoneIngress, routeTable.RouteVPCZoneIngress)
d.Set(rtIsDefault, routeTable.IsDefault)
acceptRoutesFromArray := make([]string, 0)
advertiseRoutesToArray := make([]string, 0)
for i := 0; i < len(routeTable.AcceptRoutesFrom); i++ {
acceptRoutesFromArray = append(acceptRoutesFromArray, string(*(routeTable.AcceptRoutesFrom[i].ResourceType)))
}
if err = d.Set("accept_routes_from_resource_type", acceptRoutesFromArray); err != nil {
return fmt.Errorf("[ERROR] Error setting accept_routes_from_resource_type: %s", err)
}

for i := 0; i < len(routeTable.AdvertiseRoutesTo); i++ {
advertiseRoutesToArray = append(advertiseRoutesToArray, routeTable.AdvertiseRoutesTo[i])
}

if err = d.Set("advertise_routes_to", advertiseRoutesToArray); err != nil {
return fmt.Errorf("[ERROR] Error setting advertise_routes_to: %s", err)
}

subnets := make([]map[string]interface{}, 0)

for _, s := range routeTable.Subnets {
Expand Down Expand Up @@ -320,6 +347,16 @@ func resourceIBMISVPCRoutingTableUpdate(d *schema.ResourceData, meta interface{}
routingTablePatchModel.AcceptRoutesFrom = aroutes
hasChange = true
}
if d.HasChange("advertise_routes_to") {
var advertiseRoutesToList []string
advertiseRoutesTo := d.Get("advertise_routes_to").(*schema.Set)

for _, val := range advertiseRoutesTo.List() {
advertiseRoutesToList = append(advertiseRoutesToList, val.(string))
}
routingTablePatchModel.AdvertiseRoutesTo = advertiseRoutesToList
hasChange = true
}
if d.HasChange(rtRouteDirectLinkIngress) {
routeDirectLinkIngress := d.Get(rtRouteDirectLinkIngress).(bool)
routingTablePatchModel.RouteDirectLinkIngress = core.BoolPtr(routeDirectLinkIngress)
Expand Down
29 changes: 29 additions & 0 deletions ibm/service/vpc/resource_ibm_is_vpc_routing_table_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ func ResourceIBMISVPCRoutingTableRoute() *schema.Resource {
Description: "The action to perform with a packet matching the route.",
ValidateFunc: validate.InvokeValidator("ibm_is_vpc_routing_table_route", rAction),
},
"advertise": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Indicates whether this route will be advertised to the ingress sources specified by the `advertise_routes_to` routing table property.",
},
rName: {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -242,6 +248,11 @@ func resourceIBMISVPCRoutingTableRouteCreate(d *schema.ResourceData, meta interf
createVpcRoutingTableRouteOptions.SetAction(routeAction)
}

if advertiseVal, ok := d.GetOk("advertise"); ok {
advertise := advertiseVal.(bool)
createVpcRoutingTableRouteOptions.SetAdvertise(advertise)
}

if name, ok := d.GetOk(rName); ok {
routeName := name.(string)
createVpcRoutingTableRouteOptions.SetName(routeName)
Expand Down Expand Up @@ -282,6 +293,9 @@ func resourceIBMISVPCRoutingTableRouteRead(d *schema.ResourceData, meta interfac
}

d.Set(rID, *route.ID)
if route.Advertise != nil {
d.Set("Advertise", route.Advertise)
}
d.Set(rName, *route.Name)
d.Set(rDestination, *route.Destination)
if route.NextHop != nil {
Expand Down Expand Up @@ -329,6 +343,21 @@ func resourceIBMISVPCRoutingTableRouteUpdate(d *schema.ResourceData, meta interf

// Construct an instance of the RoutePatch model
routePatchModel := new(vpcv1.RoutePatch)
if d.HasChange(rName) || d.HasChange("advertise") {
// Construct an instance of the RoutePatch model
routePatchModel := new(vpcv1.RoutePatch)
if d.HasChange(rName) {
name := d.Get(rName).(string)
routePatchModel.Name = &name
hasChange = true
}

if d.HasChange("advertise") {
advertiseVal := d.Get("advertise").(bool)
routePatchModel.Advertise = &advertiseVal
hasChange = true
}
}
if d.HasChange(rName) {
name := d.Get(rName).(string)
routePatchModel.Name = &name
Expand Down
15 changes: 11 additions & 4 deletions ibm/service/vpc/resource_ibm_is_vpc_routing_table_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,32 @@ func TestAccIBMISVPCRoutingTableRoute_basic(t *testing.T) {
routeName1 := fmt.Sprintf("tfvpcuat-create-%d", acctest.RandIntRange(10, 100))
routeTableName := fmt.Sprintf("tfvpcrt-create-%d", acctest.RandIntRange(10, 100))
routeTableName1 := fmt.Sprintf("tfvpcrt-up-create-%d", acctest.RandIntRange(10, 100))
advertiseVal := fmt.Sprintf("tfpvpcuat-create-%d", acctest.RandIntRange(10, 50))
advertiseValUpd := fmt.Sprintf("tfpvpcuat-update-%d", acctest.RandIntRange(60, 100))

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMISVPCRouteTableRouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMISVPCRouteTableRouteConfig(routeTableName, name1, subnetName, routeName),
Config: testAccCheckIBMISVPCRouteTableRouteConfig(routeTableName, name1, subnetName, routeName, advertiseVal),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMISVPCRouteTableRouteExists("ibm_is_vpc_routing_table_route.test_custom_route1", vpcRouteTables),
resource.TestCheckResourceAttr(
"ibm_is_vpc_routing_table_route.test_custom_route1", "name", routeName),
resource.TestCheckResourceAttr(
"ibm_is_vpc_routing_table_route.test_custom_route1", "advertise", advertiseVal),
),
},
{
Config: testAccCheckIBMISVPCRouteTableRouteConfig(routeTableName1, name1, subnetName, routeName1),
Config: testAccCheckIBMISVPCRouteTableRouteConfig(routeTableName1, name1, subnetName, routeName1, advertiseValUpd),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMISVPCRouteTableRouteExists("ibm_is_vpc_routing_table_route.test_custom_route1", vpcRouteTables),
resource.TestCheckResourceAttr(
"ibm_is_vpc_routing_table_route.test_custom_route1", "name", routeName1),
resource.TestCheckResourceAttr(
"ibm_is_vpc_routing_table_route.test_custom_route1", "advertise", advertiseValUpd),
),
},
},
Expand Down Expand Up @@ -114,7 +120,7 @@ func testAccCheckIBMISVPCRouteTableRouteExists(n, vpcrouteTableID string) resour
}
}

func testAccCheckIBMISVPCRouteTableRouteConfig(rtName, name, subnetName, routeName string) string {
func testAccCheckIBMISVPCRouteTableRouteConfig(rtName, name, subnetName, routeName, advertise string) string {
return fmt.Sprintf(`
resource "ibm_is_vpc" "testacc_vpc" {
name = "%s"
Expand All @@ -137,10 +143,11 @@ resource "ibm_is_vpc_routing_table_route" "test_custom_route1" {
depends_on = [ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table, ibm_is_subnet.test_cr_subnet1]
vpc = ibm_is_vpc.testacc_vpc.id
routing_table = ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table.routing_table
advertise = "%s"
name = "%s"
zone = "%s"
next_hop = "%s"
destination = ibm_is_subnet.test_cr_subnet1.ipv4_cidr_block
}
`, name, rtName, subnetName, acc.ISZoneName, acc.ISCIDR, routeName, acc.ISZoneName, acc.ISRouteNextHop)
`, name, rtName, subnetName, acc.ISZoneName, acc.ISCIDR, advertise, routeName, acc.ISZoneName, acc.ISRouteNextHop)
}
32 changes: 32 additions & 0 deletions ibm/service/vpc/resource_ibm_is_vpc_routing_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,38 @@ func TestAccIBMISVPCRoutingTable_acceptRoutesFrom(t *testing.T) {
})
}

// advertise_routes_to
func TestAccIBMISVPCRoutingTable_advertiseRoutesTO(t *testing.T) {
var vpcRouteTables string
name1 := fmt.Sprintf("tfvpc-create-%d", acctest.RandIntRange(10, 100))
routeTableName := fmt.Sprintf("tfvpcrt-create-%d", acctest.RandIntRange(10, 100))
routeTableName1 := fmt.Sprintf("tfvpcrt-up-create-%d", acctest.RandIntRange(10, 100))

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMISVPCRouteTableDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMISVPCRouteTableConfig(routeTableName, name1),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMISVPCRouteTableExists("ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table", vpcRouteTables),
resource.TestCheckResourceAttrSet(
"ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table", "advertise_routes_to"),
),
},
{
Config: testAccCheckIBMISVPCRouteTableConfig(routeTableName1, name1),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMISVPCRouteTableExists("ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table", vpcRouteTables),
resource.TestCheckResourceAttrSet(
"ibm_is_vpc_routing_table.test_ibm_is_vpc_routing_table", "advertise_routes_to"),
),
},
},
})
}

func testAccCheckIBMISVPCRouteTableDestroy(s *terraform.State) error {
//userDetails, _ := acc.TestAccProvider.Meta().(conns.ClientSession).BluemixUserDetails()

Expand Down
5 changes: 5 additions & 0 deletions website/docs/d/is_vpc_routing_table.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ In addition to all argument references listed, you can access the following attr
- `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.
- `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:</br>
**&#x2022;** `direct_link` (requires `route_direct_link_ingress` be set to `true`)</br>
**&#x2022;** `transit_gateway` (requires `route_transit_gateway_ingress` be set to `true`)
- `created_at` - (String) The date and time that this routing table was created.
- `href` - (String) The URL for this routing table.
- `id` - (String) The unique identifier of the RoutingTable.
Expand Down
Loading

0 comments on commit f2f674e

Please sign in to comment.