-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Changes from 3 commits
b7c2dbe
7153e5f
4aa4381
f7f3f25
794fe4d
98c66ca
a79361a
ca4fa3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,204 @@ | ||||||
package azurerm | ||||||
|
||||||
import ( | ||||||
"fmt" | ||||||
|
||||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-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(), | ||||||
|
||||||
"peerings": { | ||||||
Type: schema.TypeList, | ||||||
Computed: true, | ||||||
Elem: &schema.Resource{ | ||||||
Schema: map[string]*schema.Schema{ | ||||||
"peering_type": { | ||||||
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.TypeSet, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. due to a bug in Terraform Core this'll need to be a TypeList unfortunately - as such can we make this:
Suggested change
|
||||||
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.TypeSet, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (as above) since this is a Data Source there's a known bug with Sets, so can we update this to be a List:
Suggested change
|
||||||
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 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) | ||||||
} | ||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
(e.g. by removing the surrounding and then updating the
(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 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 | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package azurerm | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" | ||
) | ||
|
||
func TestAccDataSourceAzureRMExpressRoute_basic(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since there's a limit on the number of ExpressRoute's which can be provisioned at one time (and we run the tests in parallel) - we'll need to make this an internal method (by making it lower-case) and then ensure it's called from within this test function in the Express Route resource (but to make this simpler to test, we probably want to do this when all the other changes are done 😄) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it only has the 1 test in there, do we need the function? Also, should we add this function to the test function (in the resource file) or should we create a similar function in this test file? |
||
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_complete(t *testing.T) { | ||
dataSourceName := "data.azurerm_express_route_circuit.test" | ||
ri := tf.AccRandTimeInt() | ||
|
||
}*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is unused, can we remove this? |
||
|
||
func testAccDataSourceAzureRMExpressRoute_basic(rInt int, location string) string { | ||
config := testAccAzureRMExpressRouteCircuit_MeteredBasic(rInt, location) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rather than re-defining this we should be able to call the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what I meant to do. But, the subscription I used to test did not support the Express Route configuration that is hard-coded in the test you referenced. But, I checked another subscription and it looks like it does support those configurations. I'll make the change. thanks! |
||
|
||
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) | ||
} | ||
|
||
func testAccAzureRMExpressRouteCircuit_MeteredBasic(rInt int, location string) string { | ||
return fmt.Sprintf(` | ||
resource "azurerm_resource_group" "test" { | ||
name = "acctestRG-%d" | ||
location = "%s" | ||
} | ||
|
||
resource "azurerm_express_route_circuit" "test" { | ||
name = "acctest-erc-%d" | ||
location = "${azurerm_resource_group.test.location}" | ||
resource_group_name = "${azurerm_resource_group.test.name}" | ||
service_provider_name = "Equinix Test" | ||
peering_location = "Silicon Valley Test" | ||
bandwidth_in_mbps = 50 | ||
|
||
sku { | ||
tier = "Standard" | ||
family = "MeteredData" | ||
} | ||
|
||
allow_classic_operations = false | ||
|
||
tags = { | ||
Environment = "production" | ||
Purpose = "AcceptanceTests" | ||
} | ||
} | ||
`, rInt, location, rInt) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add some documentation for this data source and a link to the sidebar?