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

azurerm_web_application_firewall_policy: add http_listener_ids and path_based_rule_ids #10860

Merged
merged 6 commits into from
Mar 31, 2021
Merged
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