From 3cfd1956b7deb78eb26c1f744cd0427cc4c401ec Mon Sep 17 00:00:00 2001 From: Alvin Tang Date: Tue, 1 Sep 2020 14:42:31 +0800 Subject: [PATCH] added azurerm_lb_rule data source for #8271 --- .../services/network/client/client.go | 5 + .../services/network/lb_rule_data_source.go | 178 ++++++++++++++++++ .../internal/services/network/registration.go | 1 + .../loadbalancer_rule_data_source_test.go | 125 ++++++++++++ website/docs/d/lb_rule.html.markdown | 74 ++++++++ 5 files changed, 383 insertions(+) create mode 100644 azurerm/internal/services/network/lb_rule_data_source.go create mode 100644 azurerm/internal/services/network/tests/loadbalancer_rule_data_source_test.go create mode 100644 website/docs/d/lb_rule.html.markdown diff --git a/azurerm/internal/services/network/client/client.go b/azurerm/internal/services/network/client/client.go index e56b4f57eff2..f0edb5344f7e 100644 --- a/azurerm/internal/services/network/client/client.go +++ b/azurerm/internal/services/network/client/client.go @@ -19,6 +19,7 @@ type Client struct { ExpressRoutePeeringsClient *network.ExpressRouteCircuitPeeringsClient InterfacesClient *network.InterfacesClient LoadBalancersClient *networkLegacy.LoadBalancersClient + LoadBalancerLoadBalancingRulesClient *networkLegacy.LoadBalancerLoadBalancingRulesClient LocalNetworkGatewaysClient *network.LocalNetworkGatewaysClient PointToSiteVpnGatewaysClient *network.P2sVpnGatewaysClient ProfileClient *network.ProfilesClient @@ -87,6 +88,9 @@ func NewClient(o *common.ClientOptions) *Client { LoadBalancersClient := networkLegacy.NewLoadBalancersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&LoadBalancersClient.Client, o.ResourceManagerAuthorizer) + LoadBalancerLoadBalancingRulesClient := networkLegacy.NewLoadBalancerLoadBalancingRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&LoadBalancerLoadBalancingRulesClient.Client, o.ResourceManagerAuthorizer) + LocalNetworkGatewaysClient := network.NewLocalNetworkGatewaysClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&LocalNetworkGatewaysClient.Client, o.ResourceManagerAuthorizer) @@ -187,6 +191,7 @@ func NewClient(o *common.ClientOptions) *Client { ExpressRoutePeeringsClient: &ExpressRoutePeeringsClient, InterfacesClient: &InterfacesClient, LoadBalancersClient: &LoadBalancersClient, + LoadBalancerLoadBalancingRulesClient: &LoadBalancerLoadBalancingRulesClient, LocalNetworkGatewaysClient: &LocalNetworkGatewaysClient, PointToSiteVpnGatewaysClient: &pointToSiteVpnGatewaysClient, ProfileClient: &ProfileClient, diff --git a/azurerm/internal/services/network/lb_rule_data_source.go b/azurerm/internal/services/network/lb_rule_data_source.go new file mode 100644 index 000000000000..1281bfcfde6a --- /dev/null +++ b/azurerm/internal/services/network/lb_rule_data_source.go @@ -0,0 +1,178 @@ +package network + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network/parse" + networkValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmLoadBalancerRule() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmLoadBalancerLoadBalancingRulesRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: ValidateArmLoadBalancerRuleName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "loadbalancer_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: networkValidate.LoadBalancerID, + }, + + "frontend_ip_configuration_name": { + Type: schema.TypeString, + Computed: true, + }, + + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + + "frontend_port": { + Type: schema.TypeInt, + Computed: true, + }, + + "backend_port": { + Type: schema.TypeInt, + Computed: true, + }, + + "backend_address_pool_id": { + Type: schema.TypeString, + Computed: true, + }, + + "probe_id": { + Type: schema.TypeString, + Computed: true, + }, + + "enable_floating_ip": { + Type: schema.TypeBool, + Computed: true, + }, + + "enable_tcp_reset": { + Type: schema.TypeBool, + Computed: true, + }, + + "disable_outbound_snat": { + Type: schema.TypeBool, + Computed: true, + }, + + "idle_timeout_in_minutes": { + Type: schema.TypeInt, + Computed: true, + }, + + "load_distribution": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceArmLoadBalancerLoadBalancingRulesRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Network.LoadBalancersClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + loadBalancerID, err := parse.LoadBalancerID(d.Get("loadbalancer_id").(string)) + if err != nil { + return err + } + + loadBalancer, exists, err := retrieveLoadBalancerById(ctx, client, *loadBalancerID) + if err != nil { + return fmt.Errorf("retrieving Load Balancer by ID: %+v", err) + } + if !exists { + return fmt.Errorf("Load Balancer %q (Resource Group %q) was not found", loadBalancerID.Name, loadBalancerID.ResourceGroup) + } + + lbRuleClient := meta.(*clients.Client).Network.LoadBalancerLoadBalancingRulesClient + ctx, cancel = timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + resp, err := lbRuleClient.Get(ctx, resourceGroup, *loadBalancer.Name, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Load Balancer Rule %q was not found in Load Balancer %q (Resource Group: %q)", name, loadBalancer.Name, resourceGroup) + } + + return fmt.Errorf("Error retrieving Load Balancer %s: %s", name, err) + } + + d.SetId(*resp.ID) + + if props := resp.LoadBalancingRulePropertiesFormat; props != nil { + + frontendIPConfigurationName, err := parse.LoadBalancerFrontendIPConfigurationID(*props.FrontendIPConfiguration.ID) + if err != nil { + return err + } + + d.Set("frontend_ip_configuration_name", frontendIPConfigurationName.Name) + d.Set("protocol", props.Protocol) + d.Set("frontend_port", props.FrontendPort) + d.Set("backend_port", props.BackendPort) + + if props.BackendAddressPool != nil { + if err := d.Set("backend_address_pool_id", props.BackendAddressPool.ID); err != nil { + return fmt.Errorf("Error setting `backend_address_pool_id`: %+v", err) + } + } + + if props.Probe != nil { + if err := d.Set("probe_id", props.Probe.ID); err != nil { + return fmt.Errorf("Error setting `probe_id`: %+v", err) + } + } + + if err := d.Set("enable_floating_ip", props.EnableFloatingIP); err != nil { + return fmt.Errorf("Error setting `enable_floating_ip`: %+v", err) + } + + if err := d.Set("enable_tcp_reset", props.EnableTCPReset); err != nil { + return fmt.Errorf("Error setting `enable_tcp_reset`: %+v", err) + } + + if err := d.Set("disable_outbound_snat", props.DisableOutboundSnat); err != nil { + return fmt.Errorf("Error setting `disable_outbound_snat`: %+v", err) + } + + if err := d.Set("idle_timeout_in_minutes", props.IdleTimeoutInMinutes); err != nil { + return fmt.Errorf("Error setting `idle_timeout_in_minutes`: %+v", err) + } + + if err := d.Set("load_distribution", props.LoadDistribution); err != nil { + return fmt.Errorf("Error setting `load_distribution`: %+v", err) + } + } + + return nil +} diff --git a/azurerm/internal/services/network/registration.go b/azurerm/internal/services/network/registration.go index 8d5ac904a4f0..d983c0e25777 100644 --- a/azurerm/internal/services/network/registration.go +++ b/azurerm/internal/services/network/registration.go @@ -27,6 +27,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { "azurerm_firewall": dataSourceArmFirewall(), "azurerm_lb": dataSourceArmLoadBalancer(), "azurerm_lb_backend_address_pool": dataSourceArmLoadBalancerBackendAddressPool(), + "azurerm_lb_rule": dataSourceArmLoadBalancerRule(), "azurerm_nat_gateway": dataSourceArmNatGateway(), "azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(), "azurerm_network_interface": dataSourceArmNetworkInterface(), diff --git a/azurerm/internal/services/network/tests/loadbalancer_rule_data_source_test.go b/azurerm/internal/services/network/tests/loadbalancer_rule_data_source_test.go new file mode 100644 index 000000000000..77aa738d5b47 --- /dev/null +++ b/azurerm/internal/services/network/tests/loadbalancer_rule_data_source_test.go @@ -0,0 +1,125 @@ +package tests + +import ( + "fmt" + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccAzureRMDataSourceLoadBalancerRule_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_lb_rule", "test") + lbRuleName := fmt.Sprintf("LbRule-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDataSourceLoadBalancerRule_basic(data, lbRuleName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "frontend_ip_configuration_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "protocol"), + resource.TestCheckResourceAttrSet(data.ResourceName, "frontend_port"), + resource.TestCheckResourceAttrSet(data.ResourceName, "backend_port"), + ), + }, + }, + }) +} + +func TestAccAzureRMDataSourceLoadBalancerRule_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_lb_rule", "test") + backendPoolName := fmt.Sprintf("LbPool-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) + lbRuleName := fmt.Sprintf("LbRule-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) + probeName := fmt.Sprintf("LbProbe-%s", acctest.RandStringFromCharSet(8, acctest.CharSetAlpha)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDataSourceLoadBalancerRule_complete(data, lbRuleName, backendPoolName, probeName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "frontend_ip_configuration_name"), + resource.TestCheckResourceAttrSet(data.ResourceName, "protocol"), + resource.TestCheckResourceAttrSet(data.ResourceName, "frontend_port"), + resource.TestCheckResourceAttrSet(data.ResourceName, "backend_port"), + //optional parameters - probe_id and backend_address_pool_id are missing in testAccAzureRMDataSourceLoadBalancerRule_complete config + resource.TestCheckResourceAttrSet(data.ResourceName, "backend_address_pool_id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "probe_id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "enable_floating_ip"), + resource.TestCheckResourceAttrSet(data.ResourceName, "enable_tcp_reset"), + resource.TestCheckResourceAttrSet(data.ResourceName, "disable_outbound_snat"), + resource.TestCheckResourceAttrSet(data.ResourceName, "idle_timeout_in_minutes"), + resource.TestCheckResourceAttrSet(data.ResourceName, "load_distribution"), + ), + }, + }, + }) +} + +func testAccAzureRMDataSourceLoadBalancerRule_basic(data acceptance.TestData, name string) string { + resource := testAccAzureRMLoadBalancerRule_basic(data, name, "Basic") + return fmt.Sprintf(` +%s + +data "azurerm_lb_rule" "test" { + name = azurerm_lb_rule.test.name + resource_group_name = azurerm_lb_rule.test.resource_group_name + loadbalancer_id = azurerm_lb_rule.test.loadbalancer_id +} +`, resource) +} + +func testAccAzureRMDataSourceLoadBalancerRule_complete(data acceptance.TestData, lbRuleName string, backendPoolName string, probeName string) string { + return fmt.Sprintf(` +%s +resource "azurerm_lb_backend_address_pool" "test" { + name = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" +} + +resource "azurerm_lb_probe" "test" { + name = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + protocol = "Tcp" + port = 443 +} + +resource "azurerm_lb_rule" "test" { + name = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + loadbalancer_id = "${azurerm_lb.test.id}" + + protocol = "Tcp" + frontend_port = 3389 + backend_port = 3389 + + disable_outbound_snat = true + enable_floating_ip = true + enable_tcp_reset = true + idle_timeout_in_minutes = 10 + + backend_address_pool_id = azurerm_lb_backend_address_pool.test.id + probe_id = azurerm_lb_probe.test.id + + frontend_ip_configuration_name = azurerm_lb.test.frontend_ip_configuration.0.name +} + +data "azurerm_lb_rule" "test" { + name = azurerm_lb_rule.test.name + resource_group_name = azurerm_lb_rule.test.resource_group_name + loadbalancer_id = azurerm_lb_rule.test.loadbalancer_id +} +`, testAccAzureRMLoadBalancerRule_template(data, "Standard"), backendPoolName, probeName, lbRuleName) +} diff --git a/website/docs/d/lb_rule.html.markdown b/website/docs/d/lb_rule.html.markdown new file mode 100644 index 000000000000..c23dc295c6bb --- /dev/null +++ b/website/docs/d/lb_rule.html.markdown @@ -0,0 +1,74 @@ +--- +subcategory: "Load Balancer" +layout: "azurerm" +page_title: "Azure Resource Manager: Data Source: azurerm_lb_rule" +description: |- + Gets information about an existing Load Balancer Rule. +--- + +# Data Source: azurerm_lb_rule + +Use this data source to access information about an existing Load Balancer Rule. + +## Example Usage + +```hcl +data "azurerm_lb" "example" { + name = "example-lb" + resource_group_name = "example-resources" +} + +data "azurerm_lb_rule" "example" { + name = "first" + resource_group_name = "example-resources" + loadbalancer_id = data.azurerm_lb.example.id +} + +output "lb_rule_id" { + value = data.azurerm_lb_rule.example.id +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `loadbalancer_id` - (Required) The ID of the Load Balancer Rule. + +* `name` - (Required) The name of this Load Balancer Rule. + +* `resource_group_name` - (Required) The name of the Resource Group where the Load Balancer Rule exists. Changing this forces a new Load Balancer Rule to be created. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Load Balancer Rule. + +* `backend_address_pool_id` - A reference to a Backend Address Pool over which this Load Balancing Rule operates. + +* `probe_id` - A reference to a Probe used by this Load Balancing Rule. + +* `frontend_ip_configuration_name` - The name of the frontend IP configuration to which the rule is associated. + +* `protocol` - The transport protocol for the external endpoint. + +* `frontend_port` - The port for the external endpoint. + +* `backend_port` - The port used for internal connections on the endpoint. + +* `enable_floating_ip` - If Floating IPs are enabled for this Load Balncer Rule + +* `idle_timeout_in_minutes` - Specifies the idle timeout in minutes for TCP connections. + +* `load_distribution` - Specifies the load balancing distribution type used by the Load Balancer. + +* `disable_outbound_snat` - If snat is enabled for this Load Balancer Rule. + +* `enable_tcp_reset` - If TCP Reset is enabled for this Load Balancer Rule. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Load Balancer Rule. \ No newline at end of file