Skip to content

Commit 019b786

Browse files
committed
feat(vpn-gateway-as-spoke) - Add support for VPN Gateway as spoke of Transit Gateway
1 parent 0528bcb commit 019b786

32 files changed

+2493
-35
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ require (
3838
github.com/IBM/secrets-manager-go-sdk/v2 v2.0.15
3939
github.com/IBM/vmware-go-sdk v0.1.5
4040
github.com/IBM/vpc-beta-go-sdk v0.8.0
41-
github.com/IBM/vpc-go-sdk v0.74.1
41+
github.com/IBM/vpc-go-sdk v0.75.0
4242
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5
4343
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
4444
github.com/akamai/AkamaiOPEN-edgegrid-golang/v5 v5.0.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ github.com/IBM/vpc-beta-go-sdk v0.8.0 h1:cEPpv4iw3Ba5W2d0AWg3TIbKeJ8y1nPuUuibR5J
170170
github.com/IBM/vpc-beta-go-sdk v0.8.0/go.mod h1:hORgIyTFRzXrZIK9IohaWmCRBBlYiDRagsufi7M6akE=
171171
github.com/IBM/vpc-go-sdk v0.74.1 h1:qkWwdlILx3ZVNWht96CdlPKwhKL/y3ItN6XmwJ1rShM=
172172
github.com/IBM/vpc-go-sdk v0.74.1/go.mod h1:8lX6TpeYBbx1Vd4KTgM3PPQ4y3auGOPuD6qq3UBDdug=
173+
github.com/IBM/vpc-go-sdk v0.75.0 h1:8s11vR30n0eY9ptf6Osh9Bw13okhMVasb/KX9M52LEg=
174+
github.com/IBM/vpc-go-sdk v0.75.0/go.mod h1:8lX6TpeYBbx1Vd4KTgM3PPQ4y3auGOPuD6qq3UBDdug=
173175
github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0=
174176
github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56/go.mod h1:Zb3OT4l0mf7P/GOs2w2Ilj5sdm5Whoq3pa24dAEBHFc=
175177
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=

ibm/provider/provider.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,9 @@ func Provider() *schema.Provider {
650650

651651
"ibm_is_vpn_gateway_connection_local_cidrs": vpc.DataSourceIBMIsVPNGatewayConnectionLocalCidrs(),
652652
"ibm_is_vpn_gateway_connection_peer_cidrs": vpc.DataSourceIBMIsVPNGatewayConnectionPeerCidrs(),
653+
"ibm_is_vpn_gateway_advertised_cidrs": vpc.DataSourceIBMIsVPNGatewayAdvertisedCidrs(),
654+
"ibm_is_vpn_gateway_service_connection": vpc.DataSourceIBMIsVPNGatewayServiceConnection(),
655+
"ibm_is_vpn_gateway_service_connections": vpc.DataSourceIBMIsVPNGatewayServiceConnections(),
653656

654657
"ibm_is_vpc_default_routing_table": vpc.DataSourceIBMISVPCDefaultRoutingTable(),
655658
"ibm_is_vpc_routing_table": vpc.DataSourceIBMIsVPCRoutingTable(),
@@ -1408,6 +1411,7 @@ func Provider() *schema.Provider {
14081411
"ibm_is_volume": vpc.ResourceIBMISVolume(),
14091412
"ibm_is_vpn_gateway": vpc.ResourceIBMISVPNGateway(),
14101413
"ibm_is_vpn_gateway_connection": vpc.ResourceIBMISVPNGatewayConnection(),
1414+
"ibm_is_vpn_gateway_advertised_cidr": vpc.ResourceIBMISVPNGatewayAdvertisedCidr(),
14111415
"ibm_is_vpc": vpc.ResourceIBMISVPC(),
14121416
"ibm_is_vpc_address_prefix": vpc.ResourceIBMISVpcAddressPrefix(),
14131417
"ibm_is_vpc_dns_resolution_binding": vpc.ResourceIBMIsVPCDnsResolutionBinding(),

ibm/service/vpc/data_source_ibm_is_lb.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,6 @@ func lbGetByName(context context.Context, d *schema.ResourceData, meta interface
620620
healthMonitorInfo[healthMonitorType] = *(poolHealthMonitor.Type)
621621
pool[healthMonitor] = healthMonitorInfo
622622
}
623-
624623
if p.SessionPersistence != nil {
625624
sessionPersistenceInfo := make(map[string]interface{})
626625
sessionPersistenceInfo[sessionType] = *p.SessionPersistence.Type

ibm/service/vpc/data_source_ibm_is_vpn_gateway.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,20 @@ func DataSourceIBMISVPNGateway() *schema.Resource {
267267
Computed: true,
268268
Description: "Route mode VPN gateway.",
269269
},
270+
isVPNGatewayLocalAsn: {
271+
Type: schema.TypeInt,
272+
Computed: true,
273+
Description: "The local autonomous system number (ASN) for this VPN gateway and its connections.",
274+
},
275+
276+
isVPNGatewayAdvertisedCidrs: {
277+
Type: schema.TypeList,
278+
Computed: true,
279+
Description: "The additional CIDRs advertised through any enabled routing protocol (for example, BGP). The routing protocol will advertise routes with these CIDRs and VPC prefixes as route destinations.",
280+
Elem: &schema.Schema{
281+
Type: schema.TypeString,
282+
},
283+
},
270284
"vpc": {
271285
Type: schema.TypeList,
272286
Computed: true,
@@ -445,6 +459,16 @@ func dataSourceIBMIsVPNGatewayRead(context context.Context, d *schema.ResourceDa
445459
if err = d.Set("mode", vpnGateway.Mode); err != nil {
446460
return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting mode: %s", err), "(Data) ibm_is_vpn_gateway", "read", "set-mode").GetDiag()
447461
}
462+
if vpnGateway.AdvertisedCIDRs != nil {
463+
if err = d.Set("advertised_cidrs", vpnGateway.AdvertisedCIDRs); err != nil {
464+
return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting advertised_cidrs: %s", err), "(Data) ibm_is_vpn_gateway", "read", "set-advertised_cidrs").GetDiag()
465+
}
466+
}
467+
if vpnGateway.LocalAsn != nil {
468+
if err = d.Set("local_asn", vpnGateway.LocalAsn); err != nil {
469+
return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting local_asn: %s", err), "(Data) ibm_is_vpn_gateway", "read", "set-local_asn").GetDiag()
470+
}
471+
}
448472
if vpnGateway.VPC != nil {
449473
err = d.Set("vpc", dataSourceVPNGatewayFlattenVPC(vpnGateway.VPC))
450474
if err != nil {
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright IBM Corp. 2024 All Rights Reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package vpc
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"log"
10+
"time"
11+
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
14+
15+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
16+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
17+
"github.com/IBM/vpc-go-sdk/vpcv1"
18+
)
19+
20+
func DataSourceIBMIsVPNGatewayAdvertisedCidrs() *schema.Resource {
21+
return &schema.Resource{
22+
ReadContext: dataSourceIBMIsVPNGatewayAdvertisedCidrsRead,
23+
24+
Schema: map[string]*schema.Schema{
25+
"vpn_gateway": {
26+
Type: schema.TypeString,
27+
Optional: true,
28+
ExactlyOneOf: []string{"vpn_gateway_name", "vpn_gateway"},
29+
Description: "The VPN gateway identifier.",
30+
},
31+
"vpn_gateway_name": {
32+
Type: schema.TypeString,
33+
Optional: true,
34+
ExactlyOneOf: []string{"vpn_gateway_name", "vpn_gateway"},
35+
Description: "The VPN gateway name.",
36+
},
37+
"advertised_cidrs": {
38+
Type: schema.TypeList,
39+
Computed: true,
40+
Description: "The additional CIDRs advertised through any enabled routing protocol (for example, BGP). The routing protocol will advertise routes with these CIDRs and VPC prefixes as route destinations.",
41+
Elem: &schema.Schema{
42+
Type: schema.TypeString,
43+
},
44+
},
45+
},
46+
}
47+
}
48+
49+
func dataSourceIBMIsVPNGatewayAdvertisedCidrsRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
50+
vpcClient, err := meta.(conns.ClientSession).VpcV1API()
51+
if err != nil {
52+
tfErr := flex.TerraformErrorf(err, fmt.Sprintf("vpcClient creation failed: %s", err.Error()), "(Data) ibm_is_vpn_gateway_advertised_cidrs", "read")
53+
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
54+
return diag.FromErr(tfErr)
55+
}
56+
vpn_gateway_id := d.Get("vpn_gateway").(string)
57+
vpn_gateway_name := d.Get("vpn_gateway_name").(string)
58+
59+
if vpn_gateway_name != "" {
60+
listvpnGWOptions := vpcClient.NewListVPNGatewaysOptions()
61+
62+
start := ""
63+
allrecs := []vpcv1.VPNGatewayIntf{}
64+
for {
65+
if start != "" {
66+
listvpnGWOptions.Start = &start
67+
}
68+
availableVPNGateways, detail, err := vpcClient.ListVPNGatewaysWithContext(context, listvpnGWOptions)
69+
if err != nil || availableVPNGateways == nil {
70+
if err != nil {
71+
tfErr := flex.TerraformErrorf(err, fmt.Sprintf("Error reading list of VPN Gateways:%s\n%s", err, detail), "(Data) ibm_is_vpn_gateway_advertised_cidrs", "read")
72+
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
73+
return diag.FromErr(tfErr)
74+
}
75+
}
76+
start = flex.GetNext(availableVPNGateways.Next)
77+
allrecs = append(allrecs, availableVPNGateways.VPNGateways...)
78+
if start == "" {
79+
break
80+
}
81+
}
82+
vpn_gateway_found := false
83+
for _, vpnGatewayIntfItem := range allrecs {
84+
if *vpnGatewayIntfItem.(*vpcv1.VPNGateway).Name == vpn_gateway_name {
85+
vpnGateway := vpnGatewayIntfItem.(*vpcv1.VPNGateway)
86+
vpn_gateway_id = *vpnGateway.ID
87+
vpn_gateway_found = true
88+
break
89+
}
90+
}
91+
if !vpn_gateway_found {
92+
tfErr := flex.TerraformErrorf(err, fmt.Sprintf("No vpn gateway found with given name %s", vpn_gateway_name), "(Data) ibm_is_vpn_gateway_advertised_cidrs", "read")
93+
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
94+
return diag.FromErr(tfErr)
95+
}
96+
}
97+
98+
listVPNGatewayAdvertisedCIDRsOptions := &vpcv1.ListVPNGatewayAdvertisedCIDRsOptions{}
99+
100+
listVPNGatewayAdvertisedCIDRsOptions.SetVPNGatewayID(vpn_gateway_id)
101+
102+
vpnGatewayAdvertisedCidRs, response, err := vpcClient.ListVPNGatewayAdvertisedCIDRsWithContext(context, listVPNGatewayAdvertisedCIDRsOptions)
103+
if err != nil {
104+
tfErr := flex.TerraformErrorf(err, fmt.Sprintf("ListVPNGatewayAdvertisedCIDRsWithContext failed %s\n%s", err, response), "(Data) ibm_is_vpn_gateway_advertised_cidrs", "read")
105+
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage())
106+
return diag.FromErr(tfErr)
107+
}
108+
d.SetId(time.Now().UTC().String())
109+
d.Set("advertised_cidrs", vpnGatewayAdvertisedCidRs.AdvertisedCIDRs)
110+
111+
return nil
112+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright IBM Corp. 2024 All Rights Reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package vpc_test
5+
6+
import (
7+
"fmt"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
12+
13+
acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest"
14+
)
15+
16+
func TestAccIBMIsVPNGatewayAdvertisedCidrsDataSourceBasic(t *testing.T) {
17+
vpcname := fmt.Sprintf("tfvpnuat-vpc-%d", acctest.RandIntRange(100, 200))
18+
subnetname := fmt.Sprintf("tfvpnuat-subnet-%d", acctest.RandIntRange(100, 200))
19+
vpngwname := fmt.Sprintf("tfvpnuat-vpngw-%d", acctest.RandIntRange(100, 200))
20+
21+
resource.Test(t, resource.TestCase{
22+
PreCheck: func() { acc.TestAccPreCheck(t) },
23+
Providers: acc.TestAccProviders,
24+
Steps: []resource.TestStep{
25+
{
26+
Config: testAccCheckIBMIsVPNGatewayAdvertisedCidrsDataSourceConfigBasic(vpcname, subnetname, vpngwname),
27+
Check: resource.ComposeTestCheckFunc(
28+
resource.TestCheckResourceAttrSet("data.ibm_is_vpn_gateway_advertised_cidrs.is_vpn_gateway_advertised_cidrs", "advertised_cidrs.#"),
29+
),
30+
},
31+
},
32+
})
33+
}
34+
35+
func TestAccIBMIsVPNGatewayAdvertisedCidrsVPNGatewayNameDataSourceBasic(t *testing.T) {
36+
vpcname := fmt.Sprintf("tfvpnuat-vpc-%d", acctest.RandIntRange(100, 200))
37+
subnetname := fmt.Sprintf("tfvpnuat-subnet-%d", acctest.RandIntRange(100, 200))
38+
vpngwname := fmt.Sprintf("tfvpnuat-vpngw-%d", acctest.RandIntRange(100, 200))
39+
40+
resource.Test(t, resource.TestCase{
41+
PreCheck: func() { acc.TestAccPreCheck(t) },
42+
Providers: acc.TestAccProviders,
43+
Steps: []resource.TestStep{
44+
{
45+
Config: testAccCheckIBMIsVPNGatewayAdvertisedCidrsWithVPNGatewayNameDataSourceConfigBasic(vpcname, subnetname, vpngwname),
46+
Check: resource.ComposeTestCheckFunc(
47+
resource.TestCheckResourceAttrSet("data.ibm_is_vpn_gateway_advertised_cidrs.is_vpn_gateway_advertised_cidrs", "advertised_cidrs.#"),
48+
),
49+
},
50+
},
51+
})
52+
}
53+
54+
func testAccCheckIBMIsVPNGatewayAdvertisedCidrsDataSourceConfigBasic(vpc, subnet, vpngwname string) string {
55+
return fmt.Sprintf(`
56+
resource "ibm_is_vpc" "example" {
57+
name = "%s"
58+
}
59+
resource "ibm_is_subnet" "example" {
60+
name = "%s"
61+
vpc = ibm_is_vpc.example.id
62+
zone = "%s"
63+
ipv4_cidr_block = "%s"
64+
65+
}
66+
67+
resource "ibm_is_vpn_gateway" "example" {
68+
name = "%s"
69+
subnet = ibm_is_subnet.example.id
70+
mode = "route"
71+
local_asn = 64520
72+
lifecycle {
73+
ignore_changes = [
74+
advertised_cidrs
75+
]
76+
}
77+
}
78+
79+
resource "ibm_is_vpn_gateway_advertised_cidr" "example" {
80+
vpn_gateway = ibm_is_vpn_gateway.example.id
81+
cidr = "10.45.0.0/25"
82+
}
83+
data "ibm_is_vpn_gateway_advertised_cidrs" "is_vpn_gateway_advertised_cidrs" {
84+
depends_on = [resource.ibm_is_vpn_gateway_advertised_cidr.example]
85+
vpn_gateway = ibm_is_vpn_gateway.example.id
86+
}
87+
`, vpc, subnet, acc.ISZoneName, acc.ISCIDR, vpngwname)
88+
}
89+
90+
func testAccCheckIBMIsVPNGatewayAdvertisedCidrsWithVPNGatewayNameDataSourceConfigBasic(vpc, subnet, vpngwname string) string {
91+
return fmt.Sprintf(`
92+
resource "ibm_is_vpc" "example" {
93+
name = "%s"
94+
}
95+
resource "ibm_is_subnet" "example" {
96+
name = "%s"
97+
vpc = ibm_is_vpc.example.id
98+
zone = "%s"
99+
ipv4_cidr_block = "%s"
100+
101+
}
102+
resource "ibm_is_vpn_gateway" "example" {
103+
name = "%s"
104+
subnet = ibm_is_subnet.example.id
105+
mode = "route"
106+
lifecycle {
107+
ignore_changes = [
108+
advertised_cidrs
109+
]
110+
}
111+
}
112+
resource "ibm_is_vpn_gateway_advertised_cidr" "example" {
113+
vpn_gateway = ibm_is_vpn_gateway.example.id
114+
cidr = "10.45.0.0/25"
115+
}
116+
data "ibm_is_vpn_gateway_advertised_cidrs" "is_vpn_gateway_advertised_cidrs" {
117+
depends_on = [resource.ibm_is_vpn_gateway_advertised_cidr.example]
118+
vpn_gateway_name = ibm_is_vpn_gateway.example.name
119+
}
120+
`, vpc, subnet, acc.ISZoneName, acc.ISCIDR, vpngwname)
121+
}

0 commit comments

Comments
 (0)