Merge pull request #5032 from clstokes/f-aws-gateway-tunnel-info
provider/aws: Expose additional VPN Connection attributes.
This commit is contained in:
commit
169b63e401
|
@ -2,8 +2,10 @@ package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -15,6 +17,34 @@ import (
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type XmlVpnConnectionConfig struct {
|
||||||
|
Tunnels []XmlIpsecTunnel `xml:"ipsec_tunnel"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type XmlIpsecTunnel struct {
|
||||||
|
OutsideAddress string `xml:"vpn_gateway>tunnel_outside_address>ip_address"`
|
||||||
|
PreSharedKey string `xml:"ike>pre_shared_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TunnelInfo struct {
|
||||||
|
Tunnel1Address string
|
||||||
|
Tunnel1PreSharedKey string
|
||||||
|
Tunnel2Address string
|
||||||
|
Tunnel2PreSharedKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slice XmlVpnConnectionConfig) Len() int {
|
||||||
|
return len(slice.Tunnels)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slice XmlVpnConnectionConfig) Less(i, j int) bool {
|
||||||
|
return slice.Tunnels[i].OutsideAddress < slice.Tunnels[j].OutsideAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slice XmlVpnConnectionConfig) Swap(i, j int) {
|
||||||
|
slice.Tunnels[i], slice.Tunnels[j] = slice.Tunnels[j], slice.Tunnels[i]
|
||||||
|
}
|
||||||
|
|
||||||
func resourceAwsVpnConnection() *schema.Resource {
|
func resourceAwsVpnConnection() *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Create: resourceAwsVpnConnectionCreate,
|
Create: resourceAwsVpnConnectionCreate,
|
||||||
|
@ -56,6 +86,26 @@ func resourceAwsVpnConnection() *schema.Resource {
|
||||||
Optional: true,
|
Optional: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"tunnel1_address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"tunnel1_preshared_key": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"tunnel2_address": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"tunnel2_preshared_key": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
"routes": &schema.Schema{
|
"routes": &schema.Schema{
|
||||||
Type: schema.TypeSet,
|
Type: schema.TypeSet,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
@ -254,6 +304,13 @@ func resourceAwsVpnConnectionRead(d *schema.ResourceData, meta interface{}) erro
|
||||||
|
|
||||||
// Set read only attributes.
|
// Set read only attributes.
|
||||||
d.Set("customer_gateway_configuration", vpnConnection.CustomerGatewayConfiguration)
|
d.Set("customer_gateway_configuration", vpnConnection.CustomerGatewayConfiguration)
|
||||||
|
|
||||||
|
tunnelInfo := xmlConfigToTunnelInfo(*vpnConnection.CustomerGatewayConfiguration)
|
||||||
|
d.Set("tunnel1_address", tunnelInfo.Tunnel1Address)
|
||||||
|
d.Set("tunnel1_preshared_key", tunnelInfo.Tunnel1PreSharedKey)
|
||||||
|
d.Set("tunnel2_address", tunnelInfo.Tunnel2Address)
|
||||||
|
d.Set("tunnel2_preshared_key", tunnelInfo.Tunnel2PreSharedKey)
|
||||||
|
|
||||||
if err := d.Set("vgw_telemetry", telemetryToMapList(vpnConnection.VgwTelemetry)); err != nil {
|
if err := d.Set("vgw_telemetry", telemetryToMapList(vpnConnection.VgwTelemetry)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -355,3 +412,21 @@ func telemetryToMapList(telemetry []*ec2.VgwTelemetry) []map[string]interface{}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func xmlConfigToTunnelInfo(xmlConfig string) TunnelInfo {
|
||||||
|
var vpnConfig XmlVpnConnectionConfig
|
||||||
|
xml.Unmarshal([]byte(xmlConfig), &vpnConfig)
|
||||||
|
|
||||||
|
// don't expect consistent ordering from the XML
|
||||||
|
sort.Sort(vpnConfig)
|
||||||
|
|
||||||
|
tunnelInfo := TunnelInfo{
|
||||||
|
Tunnel1Address: vpnConfig.Tunnels[0].OutsideAddress,
|
||||||
|
Tunnel1PreSharedKey: vpnConfig.Tunnels[0].PreSharedKey,
|
||||||
|
|
||||||
|
Tunnel2Address: vpnConfig.Tunnels[1].OutsideAddress,
|
||||||
|
Tunnel2PreSharedKey: vpnConfig.Tunnels[1].PreSharedKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tunnelInfo
|
||||||
|
}
|
||||||
|
|
|
@ -117,45 +117,87 @@ func testAccAwsVpnConnection(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const testAccAwsVpnConnectionConfig = `
|
func TestAccAWSVpnConnection_xmlconfig(t *testing.T) {
|
||||||
resource "aws_vpn_gateway" "vpn_gateway" {
|
tunnelInfo := xmlConfigToTunnelInfo(testAccAwsVpnTunnelInfoXML)
|
||||||
tags {
|
if tunnelInfo.Tunnel1Address != "FIRST_ADDRESS" {
|
||||||
Name = "vpn_gateway"
|
t.Fatalf("First address from tunnel XML was incorrect.")
|
||||||
|
}
|
||||||
|
if tunnelInfo.Tunnel1PreSharedKey != "FIRST_KEY" {
|
||||||
|
t.Fatalf("First key from tunnel XML was incorrect.")
|
||||||
|
}
|
||||||
|
if tunnelInfo.Tunnel2Address != "SECOND_ADDRESS" {
|
||||||
|
t.Fatalf("Second address from tunnel XML was incorrect.")
|
||||||
|
}
|
||||||
|
if tunnelInfo.Tunnel2PreSharedKey != "SECOND_KEY" {
|
||||||
|
t.Fatalf("Second key from tunnel XML was incorrect.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testAccAwsVpnConnectionConfig = `
|
||||||
|
resource "aws_vpn_gateway" "vpn_gateway" {
|
||||||
|
tags {
|
||||||
|
Name = "vpn_gateway"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resource "aws_customer_gateway" "customer_gateway" {
|
resource "aws_customer_gateway" "customer_gateway" {
|
||||||
bgp_asn = 60000
|
bgp_asn = 60000
|
||||||
ip_address = "178.0.0.1"
|
ip_address = "178.0.0.1"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_vpn_connection" "foo" {
|
resource "aws_vpn_connection" "foo" {
|
||||||
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
||||||
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
static_routes_only = true
|
static_routes_only = true
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Change static_routes_only to be false, forcing a refresh.
|
// Change static_routes_only to be false, forcing a refresh.
|
||||||
const testAccAwsVpnConnectionConfigUpdate = `
|
const testAccAwsVpnConnectionConfigUpdate = `
|
||||||
resource "aws_vpn_gateway" "vpn_gateway" {
|
resource "aws_vpn_gateway" "vpn_gateway" {
|
||||||
tags {
|
tags {
|
||||||
Name = "vpn_gateway"
|
Name = "vpn_gateway"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_customer_gateway" "customer_gateway" {
|
resource "aws_customer_gateway" "customer_gateway" {
|
||||||
bgp_asn = 60000
|
bgp_asn = 60000
|
||||||
ip_address = "178.0.0.1"
|
ip_address = "178.0.0.1"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_vpn_connection" "foo" {
|
resource "aws_vpn_connection" "foo" {
|
||||||
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
||||||
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
static_routes_only = false
|
static_routes_only = false
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// Test our VPN tunnel config XML parsing
|
||||||
|
const testAccAwsVpnTunnelInfoXML = `
|
||||||
|
<vpn_connection id="vpn-abc123">
|
||||||
|
<ipsec_tunnel>
|
||||||
|
<vpn_gateway>
|
||||||
|
<tunnel_outside_address>
|
||||||
|
<ip_address>SECOND_ADDRESS</ip_address>
|
||||||
|
</tunnel_outside_address>
|
||||||
|
</vpn_gateway>
|
||||||
|
<ike>
|
||||||
|
<pre_shared_key>SECOND_KEY</pre_shared_key>
|
||||||
|
</ike>
|
||||||
|
</ipsec_tunnel>
|
||||||
|
<ipsec_tunnel>
|
||||||
|
<vpn_gateway>
|
||||||
|
<tunnel_outside_address>
|
||||||
|
<ip_address>FIRST_ADDRESS</ip_address>
|
||||||
|
</tunnel_outside_address>
|
||||||
|
</vpn_gateway>
|
||||||
|
<ike>
|
||||||
|
<pre_shared_key>FIRST_KEY</pre_shared_key>
|
||||||
|
</ike>
|
||||||
|
</ipsec_tunnel>
|
||||||
|
</vpn_connection>
|
||||||
|
`
|
||||||
|
|
|
@ -15,24 +15,24 @@ Provides a VPN connection connected to a VPC. These objects can be connected to
|
||||||
|
|
||||||
```
|
```
|
||||||
resource "aws_vpc" "vpc" {
|
resource "aws_vpc" "vpc" {
|
||||||
cidr_block = "10.0.0.0/16"
|
cidr_block = "10.0.0.0/16"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_vpn_gateway" "vpn_gateway" {
|
resource "aws_vpn_gateway" "vpn_gateway" {
|
||||||
vpc_id = "${aws_vpc.vpc.id}"
|
vpc_id = "${aws_vpc.vpc.id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_customer_gateway" "customer_gateway" {
|
resource "aws_customer_gateway" "customer_gateway" {
|
||||||
bgp_asn = 60000
|
bgp_asn = 60000
|
||||||
ip_address = "172.0.0.1"
|
ip_address = "172.0.0.1"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_vpn_connection" "main" {
|
resource "aws_vpn_connection" "main" {
|
||||||
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
vpn_gateway_id = "${aws_vpn_gateway.vpn_gateway.id}"
|
||||||
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
||||||
type = "ipsec.1"
|
type = "ipsec.1"
|
||||||
static_routes_only = true
|
static_routes_only = true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -55,5 +55,9 @@ The following attributes are exported:
|
||||||
* `customer_gateway_id` - The ID of the customer gateway to which the connection is attached.
|
* `customer_gateway_id` - The ID of the customer gateway to which the connection is attached.
|
||||||
* `static_routes_only` - Whether the VPN connection uses static routes exclusively.
|
* `static_routes_only` - Whether the VPN connection uses static routes exclusively.
|
||||||
* `tags` - Tags applied to the connection.
|
* `tags` - Tags applied to the connection.
|
||||||
|
* `tunnel1_address` - The public IP address of the first VPN tunnel.
|
||||||
|
* `tunnel1_preshared_key` - The preshared key of the first VPN tunnel.
|
||||||
|
* `tunnel2_address` - The public IP address of the second VPN tunnel.
|
||||||
|
* `tunnel2_preshared_key` - The preshared key of the second VPN tunnel.
|
||||||
* `type` - The type of VPN connection.
|
* `type` - The type of VPN connection.
|
||||||
* `vpn_gateway_id` - The ID of the virtual private gateway to which the connection is attached.
|
* `vpn_gateway_id` - The ID of the virtual private gateway to which the connection is attached.
|
||||||
|
|
Loading…
Reference in New Issue