Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Data Source: azurerm_express_route_circuit #3158

Merged
merged 8 commits into from
Apr 16, 2019
226 changes: 226 additions & 0 deletions azurerm/data_source_express_route_circuit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package azurerm

import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-12-01/network"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmExpressRouteCircuit() *schema.Resource {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return &schema.Resource{
Read: dataSourceArmExpressRouteCircuitRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.NoEmptyStrings,
},

"resource_group_name": resourceGroupNameForDataSourceSchema(),

"location": locationForDataSourceSchema(),

"peerings": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"peering_type": {
Type: schema.TypeString,
Computed: true,
},
"primary_peer_address_prefix": {
Type: schema.TypeString,
Computed: true,
},
"secondary_peer_address_prefix": {
Type: schema.TypeString,
Computed: true,
},
"azure_asn": {
Type: schema.TypeInt,
Computed: true,
},
"peer_asn": {
Type: schema.TypeInt,
Computed: true,
},
"vlan_id": {
Type: schema.TypeInt,
Computed: true,
},
"shared_key": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"service_key": {
Type: schema.TypeString,
Computed: true,
},

"service_provider_properties": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"service_provider_name": {
Type: schema.TypeString,
Computed: true,
},
"peering_location": {
Type: schema.TypeString,
Computed: true,
},
"bandwidth_in_mbps": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},

"service_provider_provisioning_state": {
Type: schema.TypeString,
Computed: true,
},

"sku": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"tier": {
Type: schema.TypeString,
Computed: true,
},

"family": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
}
}

func dataSourceArmExpressRouteCircuitRead(d *schema.ResourceData, meta interface{}) error {
ctx := meta.(*ArmClient).StopContext
client := meta.(*ArmClient).expressRouteCircuitClient

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: Express Route Circuit %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error making Read request on the Express Route Circuit %q (Resource Group %q): %+v", name, resourceGroup, err)
}

d.SetId(*resp.ID)

if location := resp.Location; location != nil {
d.Set("location", azureRMNormalizeLocation(*location))
}

if properties := resp.ExpressRouteCircuitPropertiesFormat; properties != nil {
peerings := flattenExpressRouteCircuitPeerings(properties.Peerings)
if err := d.Set("peerings", peerings); err != nil {
return err
}

d.Set("service_key", properties.ServiceKey)
d.Set("service_provider_provisioning_state", properties.ServiceProviderProvisioningState)

if serviceProviderProperties := flattenExpressRouteCircuitServiceProviderProperties(properties.ServiceProviderProperties); serviceProviderProperties != nil {
if err := d.Set("service_provider_properties", serviceProviderProperties); err != nil {
return fmt.Errorf("Error setting `service_provider_properties`: %+v", err)
}
}

}

if resp.Sku != nil {
sku := flattenExpressRouteCircuitSku(resp.Sku)
if err := d.Set("sku", sku); err != nil {
return fmt.Errorf("Error setting `sku`: %+v", err)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(since this is the same in the other resource, it's fine to leave this as-is for now) in general we'd tend to ensure the sku block was always set, for example by making this:

sku := flattenExpressRouteCircuitSku(resp.Sku)
if err := d.Set("sku", sku); err != nil {
  return fmt.Errorf("Error setting `sku`: %+v", err)
}

(e.g. by removing the surrounding if)

and then updating the flattenExpressRouteCircuitSku method to be:

func flattenExpressRouteCircuitSku(sku *network.ExpressRouteCircuitSku) []interface{} {
	if sku == nil {
	  return []interface{}{}
	}

	return []interface{}{
		map[string]interface{}{
			"tier":   string(sku.Tier),
			"family": string(sku.Family),
		},
	}
}

(but as mentioned above, since this is the same in the resource this is fine for now, just for info 😄)


return nil
}

func flattenExpressRouteCircuitPeerings(input *[]network.ExpressRouteCircuitPeering) []interface{} {
peerings := make([]interface{}, 0)

if input != nil {
for _, peering := range *input {
props := peering.ExpressRouteCircuitPeeringPropertiesFormat
p := make(map[string]interface{})

p["peering_type"] = string(props.PeeringType)

if primaryPeerAddressPrefix := props.PrimaryPeerAddressPrefix; primaryPeerAddressPrefix != nil {
p["primary_peer_address_prefix"] = *primaryPeerAddressPrefix
}

if secondaryPeerAddressPrefix := props.SecondaryPeerAddressPrefix; secondaryPeerAddressPrefix != nil {
p["secondary_peer_address_prefix"] = *secondaryPeerAddressPrefix
}

if azureAsn := props.AzureASN; azureAsn != nil {
p["azure_asn"] = *azureAsn
}

if peerAsn := props.PeerASN; peerAsn != nil {
p["peer_asn"] = *peerAsn
}

if vlanID := props.VlanID; vlanID != nil {
p["vlan_id"] = *vlanID
}

if sharedKey := props.SharedKey; sharedKey != nil {
p["shared_key"] = *sharedKey
}

peerings = append(peerings, p)
}
}

return peerings
}

func flattenExpressRouteCircuitServiceProviderProperties(input *network.ExpressRouteCircuitServiceProviderProperties) []interface{} {
serviceProviderProperties := make([]interface{}, 0)

if input != nil {
p := make(map[string]interface{})

if serviceProviderName := input.ServiceProviderName; serviceProviderName != nil {
p["service_provider_name"] = *serviceProviderName
}

if peeringLocation := input.PeeringLocation; peeringLocation != nil {
p["peering_location"] = *peeringLocation
}

if bandwidthInMbps := input.BandwidthInMbps; bandwidthInMbps != nil {
p["bandwidth_in_mbps"] = *bandwidthInMbps
}

serviceProviderProperties = append(serviceProviderProperties, p)
}

return serviceProviderProperties
}
47 changes: 47 additions & 0 deletions azurerm/data_source_express_route_circuit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
)

func testAccDataSourceAzureRMExpressRoute_basicMetered(t *testing.T) {
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
dataSourceName := "data.azurerm_express_route_circuit.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMExpressRouteCircuitDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMExpressRoute_basic(ri, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.service_provider_name", "Equinix Test"),
resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.peering_location", "Silicon Valley Test"),
resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.bandwidth_in_mbps", "50"),
resource.TestCheckResourceAttr(dataSourceName, "sku.0.tier", "Standard"),
resource.TestCheckResourceAttr(dataSourceName, "sku.0.family", "MeteredData"),
resource.TestCheckResourceAttr(dataSourceName, "service_provider_provisioning_state", "NotProvisioned"),
),
},
},
})
}

func testAccDataSourceAzureRMExpressRoute_basic(rInt int, location string) string {
config := testAccAzureRMExpressRouteCircuit_basicMeteredConfig(rInt, location)

return fmt.Sprintf(`
%s

data "azurerm_express_route_circuit" test {
resource_group_name = "${azurerm_resource_group.test.name}"
name = "${azurerm_express_route_circuit.test.name}"
}
`, config)
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_dev_test_lab": dataSourceArmDevTestLab(),
"azurerm_dns_zone": dataSourceArmDnsZone(),
"azurerm_eventhub_namespace": dataSourceEventHubNamespace(),
"azurerm_express_route_circuit": dataSourceArmExpressRouteCircuit(),
"azurerm_firewall": dataSourceArmFirewall(),
"azurerm_image": dataSourceArmImage(),
"azurerm_hdinsight_cluster": dataSourceArmHDInsightSparkCluster(),
Expand Down
11 changes: 11 additions & 0 deletions azurerm/resource_arm_virtual_network_gateway_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ func resourceArmVirtualNetworkGatewayConnection() *schema.Resource {
Sensitive: true,
},

"express_route_gateway_bypass": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},

"ipsec_policy": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -350,6 +356,10 @@ func resourceArmVirtualNetworkGatewayConnectionRead(d *schema.ResourceData, meta
d.Set("shared_key", conn.SharedKey)
}

if conn.ExpressRouteGatewayBypass != nil {
d.Set("express_route_gateway_bypass", conn.ExpressRouteGatewayBypass)
}

if conn.IpsecPolicies != nil {
ipsecPolicies := flattenArmVirtualNetworkGatewayConnectionIpsecPolicies(conn.IpsecPolicies)

Expand Down Expand Up @@ -390,6 +400,7 @@ func getArmVirtualNetworkGatewayConnectionProperties(d *schema.ResourceData) (*n
props := &network.VirtualNetworkGatewayConnectionPropertiesFormat{
ConnectionType: connectionType,
EnableBgp: utils.Bool(d.Get("enable_bgp").(bool)),
ExpressRouteGatewayBypass: utils.Bool(d.Get("express_route_gateway_bypass").(bool)),
UsePolicyBasedTrafficSelectors: utils.Bool(d.Get("use_policy_based_traffic_selectors").(bool)),
}

Expand Down
4 changes: 4 additions & 0 deletions website/azurerm.erb
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@
<a href="/docs/providers/azurerm/d/eventhub_namespace.html">azurerm_eventhub_namespace</a>
</li>

<li<%= sidebar_current("docs-azurerm-datasource-express-route-circuit") %>>
<a href="/docs/providers/azurerm/d/express_route_circuit.html">azurerm_express_route_circuit</a>
</li>

<li<%= sidebar_current("docs-azurerm-datasource-firewall") %>>
<a href="/docs/providers/azurerm/d/firewall.html">azurerm_firewall</a>
</li>
Expand Down
Loading