diff --git a/azurerm/data_source_express_route_circuit.go b/azurerm/data_source_express_route_circuit.go new file mode 100644 index 000000000000..d733e9d96dfe --- /dev/null +++ b/azurerm/data_source_express_route_circuit.go @@ -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 { + 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) + } + } + + 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 +} diff --git a/azurerm/data_source_express_route_circuit_test.go b/azurerm/data_source_express_route_circuit_test.go new file mode 100644 index 000000000000..d2932c4816b3 --- /dev/null +++ b/azurerm/data_source_express_route_circuit_test.go @@ -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) { + 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"), + resource.TestCheckResourceAttr(dataSourceName, "service_provider_properties.0.peering_location", "Silicon Valley"), + 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) +} diff --git a/azurerm/provider.go b/azurerm/provider.go index 6d5afaa9d7a5..b3174d38fb16 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -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(), diff --git a/azurerm/resource_arm_express_route_circuit_test.go b/azurerm/resource_arm_express_route_circuit_test.go index 218e77a53b2a..0e3a61596352 100644 --- a/azurerm/resource_arm_express_route_circuit_test.go +++ b/azurerm/resource_arm_express_route_circuit_test.go @@ -25,6 +25,7 @@ func TestAccAzureRMExpressRouteCircuit(t *testing.T) { "premiumUnlimited": testAccAzureRMExpressRouteCircuit_premiumUnlimited, "allowClassicOperationsUpdate": testAccAzureRMExpressRouteCircuit_allowClassicOperationsUpdate, "requiresImport": testAccAzureRMExpressRouteCircuit_requiresImport, + "data_basic": testAccDataSourceAzureRMExpressRoute_basicMetered, }, "PrivatePeering": { "azurePrivatePeering": testAccAzureRMExpressRouteCircuitPeering_azurePrivatePeering, diff --git a/azurerm/resource_arm_virtual_network_gateway_connection.go b/azurerm/resource_arm_virtual_network_gateway_connection.go index 8677e0430af7..ec76fa9b9c45 100644 --- a/azurerm/resource_arm_virtual_network_gateway_connection.go +++ b/azurerm/resource_arm_virtual_network_gateway_connection.go @@ -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, @@ -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) @@ -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)), } diff --git a/website/azurerm.erb b/website/azurerm.erb index 1d0dc2dc1cc0..caf5d8b9d081 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -155,6 +155,10 @@ azurerm_eventhub_namespace +