Skip to content

Commit

Permalink
azurerm_web_application_firewall_policy: add http_listener_ids and pa…
Browse files Browse the repository at this point in the history
…th_based_rule_ids (#10860)

Fixes #10859.

Not sure about the syntax in the acceptance test when referencing the path based rule IDs.
  • Loading branch information
sirlatrom authored Mar 31, 2021
1 parent 19c81ef commit a4cdb25
Show file tree
Hide file tree
Showing 13 changed files with 850 additions and 3 deletions.
150 changes: 150 additions & 0 deletions azurerm/internal/services/network/application_gateway_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,21 @@ func TestAccApplicationGateway_customHttpListenerFirewallPolicy(t *testing.T) {
})
}

func TestAccApplicationGateway_customHttpListenerFirewallPolicyWithAssociations(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_application_gateway", "test")
r := ApplicationGatewayResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.customHttpListenerFirewallPolicyWithAssociations(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

// TODO required soft delete on the keyvault
func TestAccApplicationGateway_trustedRootCertificate_keyvault(t *testing.T) {
t.Skip()
Expand Down Expand Up @@ -2085,6 +2100,141 @@ resource "azurerm_application_gateway" "test" {
`, r.template(data), data.RandomInteger)
}

func (r ApplicationGatewayResource) customHttpListenerFirewallPolicyWithAssociations(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
# since these variables are re-used - a locals block makes this more maintainable
locals {
backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap"
frontend_port_name = "${azurerm_virtual_network.test.name}-feport"
frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip"
http_setting_name = "${azurerm_virtual_network.test.name}-be-htst"
listener_name = "${azurerm_virtual_network.test.name}-httplstn"
request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt"
}
resource "azurerm_public_ip" "teststd" {
name = "acctest-PubIpStd-%[2]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_application_gateway" "test" {
name = "acctestag-%[2]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
sku {
name = "WAF_v2"
tier = "WAF_v2"
capacity = 2
}
gateway_ip_configuration {
name = "my-gateway-ip-configuration"
subnet_id = azurerm_subnet.test.id
}
frontend_port {
name = local.frontend_port_name
port = 80
}
frontend_ip_configuration {
name = local.frontend_ip_configuration_name
public_ip_address_id = azurerm_public_ip.teststd.id
}
backend_address_pool {
name = local.backend_address_pool_name
}
backend_http_settings {
name = local.http_setting_name
cookie_based_affinity = "Disabled"
port = 443
protocol = "Https"
request_timeout = 1
pick_host_name_from_backend_address = true
}
http_listener {
name = local.listener_name
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = local.frontend_port_name
protocol = "Http"
firewall_policy_id = azurerm_web_application_firewall_policy.testfwp_listener.id
}
request_routing_rule {
name = local.request_routing_rule_name
rule_type = "Basic"
http_listener_name = local.listener_name
backend_address_pool_name = local.backend_address_pool_name
backend_http_settings_name = local.http_setting_name
}
url_path_map {
name = local.url_path_map_name
default_backend_address_pool_name = local.backend_address_pool_name
default_backend_http_settings_name = local.http_setting_name
path_rule {
name = local.path_rule_name
backend_address_pool_name = local.backend_address_pool_name
backend_http_settings_name = local.http_setting_name
paths = [
"/test",
]
}
}
}
resource "azurerm_web_application_firewall_policy" "testfwp" {
name = "acctest-fwp-%[2]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
policy_settings {
enabled = true
mode = "Prevention"
}
managed_rules {
managed_rule_set {
type = "OWASP"
version = "3.1"
}
}
}
resource "azurerm_web_application_firewall_policy" "testfwp_listener" {
name = "acctest-fwp-listener-%[2]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
http_listener_ids = [for v in azurerm_application_gateway.test.http_listener : v.id]
path_based_rule_ids = flatten([for v in azurerm_application_gateway.test.url_path_map : [for w in v.path_rule : w.id]])
policy_settings {
enabled = true
mode = "Prevention"
}
managed_rules {
managed_rule_set {
type = "OWASP"
version = "3.1"
}
}
}
`, r.template(data), data.RandomInteger)
}

func (r ApplicationGatewayResource) authCertificateUpdated(data acceptance.TestData) string {
return fmt.Sprintf(`
%[1]s
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type ApplicationGatewayHTTPListenerId struct {
SubscriptionId string
ResourceGroup string
ApplicationGatewayName string
HttpListenerName string
}

func NewApplicationGatewayHTTPListenerID(subscriptionId, resourceGroup, applicationGatewayName, httpListenerName string) ApplicationGatewayHTTPListenerId {
return ApplicationGatewayHTTPListenerId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
ApplicationGatewayName: applicationGatewayName,
HttpListenerName: httpListenerName,
}
}

func (id ApplicationGatewayHTTPListenerId) String() string {
segments := []string{
fmt.Sprintf("Http Listener Name %q", id.HttpListenerName),
fmt.Sprintf("Application Gateway Name %q", id.ApplicationGatewayName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Application Gateway H T T P Listener", segmentsStr)
}

func (id ApplicationGatewayHTTPListenerId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/applicationGateways/%s/httpListeners/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.ApplicationGatewayName, id.HttpListenerName)
}

// ApplicationGatewayHTTPListenerID parses a ApplicationGatewayHTTPListener ID into an ApplicationGatewayHTTPListenerId struct
func ApplicationGatewayHTTPListenerID(input string) (*ApplicationGatewayHTTPListenerId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := ApplicationGatewayHTTPListenerId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.ApplicationGatewayName, err = id.PopSegment("applicationGateways"); err != nil {
return nil, err
}
if resourceId.HttpListenerName, err = id.PopSegment("httpListeners"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid"
)

var _ resourceid.Formatter = ApplicationGatewayHTTPListenerId{}

func TestApplicationGatewayHTTPListenerIDFormatter(t *testing.T) {
actual := NewApplicationGatewayHTTPListenerID("12345678-1234-9876-4563-123456789012", "resGroup1", "applicationGateway1", "httpListener1").ID()
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/applicationGateways/applicationGateway1/httpListeners/httpListener1"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestApplicationGatewayHTTPListenerID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *ApplicationGatewayHTTPListenerId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing SubscriptionId
Input: "/",
Error: true,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Error: true,
},

{
// missing ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/",
Error: true,
},

{
// missing value for ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/",
Error: true,
},

{
// missing ApplicationGatewayName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/",
Error: true,
},

{
// missing value for ApplicationGatewayName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/applicationGateways/",
Error: true,
},

{
// missing HttpListenerName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/applicationGateways/applicationGateway1/",
Error: true,
},

{
// missing value for HttpListenerName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/applicationGateways/applicationGateway1/httpListeners/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/applicationGateways/applicationGateway1/httpListeners/httpListener1",
Expected: &ApplicationGatewayHTTPListenerId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
ResourceGroup: "resGroup1",
ApplicationGatewayName: "applicationGateway1",
HttpListenerName: "httpListener1",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/APPLICATIONGATEWAY1/HTTPLISTENERS/HTTPLISTENER1",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := ApplicationGatewayHTTPListenerID(v.Input)
if err != nil {
if v.Error {
continue
}

t.Fatalf("Expect a value but got an error: %s", err)
}
if v.Error {
t.Fatal("Expect an error but didn't get one")
}

if actual.SubscriptionId != v.Expected.SubscriptionId {
t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId)
}
if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup)
}
if actual.ApplicationGatewayName != v.Expected.ApplicationGatewayName {
t.Fatalf("Expected %q but got %q for ApplicationGatewayName", v.Expected.ApplicationGatewayName, actual.ApplicationGatewayName)
}
if actual.HttpListenerName != v.Expected.HttpListenerName {
t.Fatalf("Expected %q but got %q for HttpListenerName", v.Expected.HttpListenerName, actual.HttpListenerName)
}
}
}
Loading

0 comments on commit a4cdb25

Please sign in to comment.