Skip to content

Commit 6f33066

Browse files
nombiezinjasmaantbcmdarroch
committed
HCCP-91 HVN route resource (#122)
* added create, scaffolded read and delete for hvn route resource * Adds delete for HVN route resource * Adds hvn route import function * Handle both peering and tgw attachment resource types in HVN route resources * Regenerate docs, add example s for hvn route resource * Re-run go generate after adding example * ACreate hvn route function checks for target existence before proceeding * Add peering to example for hvn route, regenerate docs * Resolves comments - better logging and commenting for HVN route resource * removed unnecessary validation * removed todos * removed tgw attachment from hvn route example * added examples of the hvn route target * moved hvn route creation into clients * simplified parsing target_link for the hvn route resource * dropped checking for hvn route existance * fixed hvn routes import * gofmt hvn_route.go * redo hvn route import to use route ID * go mod tidy * redo hvn route datasource to use route ID * renamed hvn -> hvn_link * refactored WaitForHVNRouteToBeActive * unified hvn route errors/logs * small refactoring * improved logs * messages improvements Co-authored-by: Brenna Hewer-Darroch <[email protected]> * regenarated docs Co-authored-by: Anton Panferov <[email protected]> Co-authored-by: Brenna Hewer-Darroch <[email protected]>
1 parent 7304bc1 commit 6f33066

File tree

14 files changed

+575
-43
lines changed

14 files changed

+575
-43
lines changed

docs/data-sources/hvn_route.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ The HVN route data source provides information about an existing HVN route.
1515

1616
```terraform
1717
data "hcp_hvn_route" "example" {
18-
hvn = var.hvn
19-
destination_cidr = var.destination_cidr
18+
hvn_link = var.hvn_link
19+
destination_cidr = var.hvn_route_id
2020
}
2121
```
2222

@@ -25,8 +25,8 @@ data "hcp_hvn_route" "example" {
2525

2626
### Required
2727

28-
- **destination_cidr** (String) The destination CIDR of the HVN route
29-
- **hvn** (String) The `self_link` of the HashiCorp Virtual Network (HVN).
28+
- **hvn_link** (String) The `self_link` of the HashiCorp Virtual Network (HVN).
29+
- **hvn_route_id** (String) The ID of the HVN route.
3030

3131
### Optional
3232

@@ -36,6 +36,7 @@ data "hcp_hvn_route" "example" {
3636
### Read-Only
3737

3838
- **created_at** (String) The time that the HVN route was created.
39+
- **destination_cidr** (String) The destination CIDR of the HVN route.
3940
- **self_link** (String) A unique URL identifying the HVN route.
4041
- **state** (String) The state of the HVN route.
4142
- **target_link** (String) A unique URL identifying the target of the HVN route.

docs/resources/hvn_route.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "hcp_hvn_route Resource - terraform-provider-hcp"
4+
subcategory: ""
5+
description: |-
6+
The HVN route resource allows you to manage an HVN route.
7+
---
8+
9+
# hcp_hvn_route (Resource)
10+
11+
The HVN route resource allows you to manage an HVN route.
12+
13+
## Example Usage
14+
15+
```terraform
16+
provider "aws" {
17+
region = "us-west-2"
18+
}
19+
20+
resource "hcp_hvn" "main" {
21+
hvn_id = "main-hvn"
22+
cloud_provider = "aws"
23+
region = "us-west-2"
24+
cidr_block = "172.25.16.0/20"
25+
}
26+
27+
// Creating a peering and a route for it.
28+
resource "aws_vpc" "peer" {
29+
cidr_block = "192.168.0.0/20"
30+
}
31+
32+
resource "hcp_aws_network_peering" "example" {
33+
peering_id = "peer-example"
34+
hvn_id = hcp_hvn.main.hvn_id
35+
peer_vpc_id = aws_vpc.peer.id
36+
peer_account_id = aws_vpc.peer.owner_id
37+
peer_vpc_region = "us-west-2"
38+
}
39+
40+
resource "aws_vpc_peering_connection_accepter" "peer" {
41+
vpc_peering_connection_id = hcp_aws_network_peering.example.provider_peering_id
42+
auto_accept = true
43+
}
44+
45+
resource "hcp_hvn_route" "example-peering-route" {
46+
hvn_link = hcp_hvn.main.self_link
47+
hvn_route_id = "peering-route"
48+
destination_cidr = aws_vpc.peer.cidr_block
49+
target_link = hcp_aws_network_peering.example.self_link
50+
}
51+
```
52+
53+
<!-- schema generated by tfplugindocs -->
54+
## Schema
55+
56+
### Required
57+
58+
- **destination_cidr** (String) The destination CIDR of the HVN route.
59+
- **hvn_link** (String) The `self_link` of the HashiCorp Virtual Network (HVN).
60+
- **hvn_route_id** (String) The ID of the HVN route.
61+
- **target_link** (String) A unique URL identifying the target of the HVN route. Examples of the target: [`aws_network_peering`](aws_network_peering.md), [`aws_transit_gateway_attachment`](aws_transit_gateway_attachment.md)
62+
63+
### Optional
64+
65+
- **id** (String) The ID of this resource.
66+
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
67+
68+
### Read-Only
69+
70+
- **created_at** (String) The time that the HVN route was created.
71+
- **self_link** (String) A unique URL identifying the HVN route.
72+
- **state** (String) The state of the HVN route.
73+
74+
<a id="nestedblock--timeouts"></a>
75+
### Nested Schema for `timeouts`
76+
77+
Optional:
78+
79+
- **create** (String)
80+
- **default** (String)
81+
82+
## Import
83+
84+
Import is supported using the following syntax:
85+
86+
```shell
87+
# The import ID is {hvn_id}:{hvn_route_id}
88+
terraform import hcp_hvn_route.example main-hvn:example-hvn-route
89+
```
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
data "hcp_hvn_route" "example" {
2-
hvn = var.hvn
3-
destination_cidr = var.destination_cidr
2+
hvn_link = var.hvn_link
3+
destination_cidr = var.hvn_route_id
44
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
variable "hvn" {
1+
variable "hvn_link" {
22
description = "The `self_link` of the HashiCorp Virtual Network (HVN)."
33
type = string
44
}
55

6-
variable "destination_cidr" {
7-
description = "The destination CIDR of the HVN route."
6+
variable "hvn_route_id" {
7+
description = "The ID of the HVN route ID."
88
type = string
99
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# The import ID is {hvn_id}:{hvn_route_id}
2+
terraform import hcp_hvn_route.example main-hvn:example-hvn-route
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
provider "aws" {
2+
region = "us-west-2"
3+
}
4+
5+
resource "hcp_hvn" "main" {
6+
hvn_id = "main-hvn"
7+
cloud_provider = "aws"
8+
region = "us-west-2"
9+
cidr_block = "172.25.16.0/20"
10+
}
11+
12+
// Creating a peering and a route for it.
13+
resource "aws_vpc" "peer" {
14+
cidr_block = "192.168.0.0/20"
15+
}
16+
17+
resource "hcp_aws_network_peering" "example" {
18+
peering_id = "peer-example"
19+
hvn_id = hcp_hvn.main.hvn_id
20+
peer_vpc_id = aws_vpc.peer.id
21+
peer_account_id = aws_vpc.peer.owner_id
22+
peer_vpc_region = "us-west-2"
23+
}
24+
25+
resource "aws_vpc_peering_connection_accepter" "peer" {
26+
vpc_peering_connection_id = hcp_aws_network_peering.example.provider_peering_id
27+
auto_accept = true
28+
}
29+
30+
resource "hcp_hvn_route" "example-peering-route" {
31+
hvn_link = hcp_hvn.main.self_link
32+
hvn_route_id = "peering-route"
33+
destination_cidr = aws_vpc.peer.cidr_block
34+
target_link = hcp_aws_network_peering.example.self_link
35+
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/google/uuid v1.2.0
1111
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
1212
github.com/hashicorp/hcl/v2 v2.8.2 // indirect
13-
github.com/hashicorp/hcp-sdk-go v0.7.0
13+
github.com/hashicorp/hcp-sdk-go v0.8.0
1414
github.com/hashicorp/terraform-exec v0.13.3 // indirect
1515
github.com/hashicorp/terraform-plugin-docs v0.4.0
1616
github.com/hashicorp/terraform-plugin-sdk/v2 v2.5.0

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
325325
github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8=
326326
github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY=
327327
github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
328-
github.com/hashicorp/hcp-sdk-go v0.7.0 h1:OtbcR/rMBlfK5BLowHIPe0HJtb0rEs8FyRAzS+xH9vI=
329-
github.com/hashicorp/hcp-sdk-go v0.7.0/go.mod h1:M+kmFj0s4KWNA5GVOgLhNtCTu3ypTR+QjWYIMgedA5Q=
328+
github.com/hashicorp/hcp-sdk-go v0.8.0 h1:P7mMk2h87BYJ6dk851pD3WvnuXa17hxvutA5slxCWGU=
329+
github.com/hashicorp/hcp-sdk-go v0.8.0/go.mod h1:M+kmFj0s4KWNA5GVOgLhNtCTu3ypTR+QjWYIMgedA5Q=
330330
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
331331
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
332332
github.com/hashicorp/terraform-exec v0.12.0/go.mod h1:SGhto91bVRlgXQWcJ5znSz+29UZIa8kpBbkGwQ+g9E8=

internal/clients/hvn_route.go

+124
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,68 @@ package clients
22

33
import (
44
"context"
5+
"fmt"
6+
"log"
7+
"time"
58

69
"github.com/hashicorp/hcp-sdk-go/clients/cloud-network/preview/2020-09-07/client/network_service"
710
networkmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-network/preview/2020-09-07/models"
811
sharedmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
913
)
1014

15+
// CreateHVNRoute creates a new HVN route
16+
func CreateHVNRoute(ctx context.Context, client *Client,
17+
id string,
18+
hvn *sharedmodels.HashicorpCloudLocationLink,
19+
destination string,
20+
target *sharedmodels.HashicorpCloudLocationLink,
21+
location *sharedmodels.HashicorpCloudLocationLocation) (*networkmodels.HashicorpCloudNetwork20200907CreateHVNRouteResponse, error) {
22+
23+
hvnRouteParams := network_service.NewCreateHVNRouteParams()
24+
hvnRouteParams.Context = ctx
25+
hvnRouteParams.HvnLocationOrganizationID = location.OrganizationID
26+
hvnRouteParams.HvnLocationProjectID = location.ProjectID
27+
hvnRouteParams.HvnID = hvn.ID
28+
hvnRouteParams.Body = &networkmodels.HashicorpCloudNetwork20200907CreateHVNRouteRequest{
29+
Destination: destination,
30+
Hvn: hvn,
31+
ID: id,
32+
Target: &networkmodels.HashicorpCloudNetwork20200907HVNRouteTarget{
33+
HvnConnection: target,
34+
},
35+
}
36+
log.Printf("[INFO] Creating HVN route for HVN (%s) with destination CIDR %s", hvn.ID, destination)
37+
hvnRouteResp, err := client.Network.CreateHVNRoute(hvnRouteParams, nil)
38+
if err != nil {
39+
return nil, fmt.Errorf("unable to create HVN route for HVN (%s) with destination CIDR %s: %v", hvn.ID, destination, err)
40+
}
41+
42+
return hvnRouteResp.Payload, nil
43+
}
44+
45+
// GetHVNRoute returns specific HVN route by its ID
46+
func GetHVNRoute(ctx context.Context, client *Client, hvnID, routeID string, loc *sharedmodels.HashicorpCloudLocationLocation) (*networkmodels.HashicorpCloudNetwork20200907HVNRoute, error) {
47+
getHVNRouteParams := network_service.NewGetHVNRouteParams()
48+
getHVNRouteParams.Context = ctx
49+
getHVNRouteParams.HvnID = hvnID
50+
getHVNRouteParams.ID = routeID
51+
getHVNRouteParams.HvnLocationOrganizationID = loc.OrganizationID
52+
getHVNRouteParams.HvnLocationProjectID = loc.ProjectID
53+
54+
getHVNRouteResponse, err := client.Network.GetHVNRoute(getHVNRouteParams, nil)
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
return getHVNRouteResponse.Payload.Route, nil
60+
}
61+
1162
// ListHVNRoutes lists the routes for an HVN.
1263
func ListHVNRoutes(ctx context.Context, client *Client, hvnID string,
1364
destination string, targetID string, targetType string,
1465
loc *sharedmodels.HashicorpCloudLocationLocation) ([]*networkmodels.HashicorpCloudNetwork20200907HVNRoute, error) {
66+
1567
listHVNRoutesParams := network_service.NewListHVNRoutesParams()
1668
listHVNRoutesParams.Context = ctx
1769
listHVNRoutesParams.HvnID = hvnID
@@ -28,3 +80,75 @@ func ListHVNRoutes(ctx context.Context, client *Client, hvnID string,
2880

2981
return listHVNRoutesResponse.Payload.Routes, nil
3082
}
83+
84+
// DeleteSnapshotByID deletes an HVN route by its ID
85+
func DeleteHVNRouteByID(ctx context.Context, client *Client, hvnID string,
86+
hvnRouteID string, loc *sharedmodels.HashicorpCloudLocationLocation) (*networkmodels.HashicorpCloudNetwork20200907DeleteHVNRouteResponse, error) {
87+
88+
deleteHVNRouteParams := network_service.NewDeleteHVNRouteParams()
89+
90+
deleteHVNRouteParams.Context = ctx
91+
deleteHVNRouteParams.ID = hvnRouteID
92+
deleteHVNRouteParams.HvnID = hvnID
93+
deleteHVNRouteParams.HvnLocationOrganizationID = loc.OrganizationID
94+
deleteHVNRouteParams.HvnLocationProjectID = loc.ProjectID
95+
96+
deleteHVNRouteResponse, err := client.Network.DeleteHVNRoute(deleteHVNRouteParams, nil)
97+
if err != nil {
98+
return nil, err
99+
}
100+
101+
return deleteHVNRouteResponse.Payload, nil
102+
}
103+
104+
const (
105+
// HvnRouteStateCreating is the CREATING state of an HVN route
106+
HvnRouteStateCreating = string(networkmodels.HashicorpCloudNetwork20200907HVNRouteStateCREATING)
107+
108+
// HvnRouteStateActive is the ACTIVE state of an HVN route
109+
HvnRouteStateActive = string(networkmodels.HashicorpCloudNetwork20200907HVNRouteStateACTIVE)
110+
111+
// HvnRouteStatePending is the PENDING state of an HVN route
112+
HvnRouteStatePending = string(networkmodels.HashicorpCloudNetwork20200907HVNRouteStatePENDING)
113+
)
114+
115+
// hvnRouteRefreshState refreshes the state of the HVN route
116+
func hvnRouteRefreshState(ctx context.Context, client *Client, hvnID, routeID string, loc *sharedmodels.HashicorpCloudLocationLocation) resource.StateRefreshFunc {
117+
return func() (interface{}, string, error) {
118+
route, err := GetHVNRoute(ctx, client, hvnID, routeID, loc)
119+
if err != nil {
120+
return nil, "", err
121+
}
122+
123+
return route, string(route.State), nil
124+
}
125+
}
126+
127+
// WaitForHVNRouteToBeActive will poll the GET HVN route endpoint until
128+
// the state is ACTIVE, ctx is canceled, or an error occurs.
129+
func WaitForHVNRouteToBeActive(ctx context.Context, client *Client,
130+
hvnID string,
131+
routeID string,
132+
loc *sharedmodels.HashicorpCloudLocationLocation,
133+
timeout time.Duration) (*networkmodels.HashicorpCloudNetwork20200907HVNRoute, error) {
134+
135+
stateChangeConf := resource.StateChangeConf{
136+
Pending: []string{
137+
HvnRouteStateCreating,
138+
HvnRouteStatePending,
139+
},
140+
Target: []string{
141+
HvnRouteStateActive,
142+
},
143+
Refresh: hvnRouteRefreshState(ctx, client, hvnID, routeID, loc),
144+
Timeout: timeout,
145+
PollInterval: 5 * time.Second,
146+
}
147+
148+
result, err := stateChangeConf.WaitForStateContext(ctx)
149+
if err != nil {
150+
return nil, fmt.Errorf("error waiting for the HVN route (%s) to become 'ACTIVE': %+v", routeID, err)
151+
}
152+
153+
return result.(*networkmodels.HashicorpCloudNetwork20200907HVNRoute), nil
154+
}

0 commit comments

Comments
 (0)