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_application_gateway - support for redirect rules #2908

Merged
merged 26 commits into from
Mar 21, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0b2658a
WIP initial schema
RustyF Feb 6, 2019
188b3ac
Fleshed out implementation and adjusted schema to align with azure AP…
RustyF Feb 18, 2019
7f16cdc
Documentation draft
Feb 18, 2019
a74ff57
Test WIP
Feb 18, 2019
b299e85
Ensure we can name redirect from routing rule
RustyF Feb 18, 2019
2979ffa
First stab at test for target httpListener scenario
RustyF Feb 18, 2019
ddbf0f4
Missing computed ID properties (finally understand how they work)
RustyF Feb 20, 2019
1ff625c
Mis-spelt variable
RustyF Feb 20, 2019
a9ca44d
Use Go Azure SDK constants
RustyF Feb 24, 2019
91abb6e
Declare some mutual exclusions using ConflictsWith...
RustyF Feb 24, 2019
cbdd835
Ensure http_listener optional now (in case of redirection)
RustyF Feb 27, 2019
db7aef2
Correction - HTTPListener required on routing rule
RustyF Feb 27, 2019
2fc242e
tests for basic and path-based routing rules with redirection in plac…
RustyF Feb 27, 2019
5d18d1e
Validate for no empty strings
RustyF Feb 28, 2019
32cdb89
Introduce NilOrEmpty() validation to correctly check strings, i.e. Ta…
RustyF Mar 3, 2019
be131cf
Fixed bug where wrong local was referenced.
RustyF Mar 3, 2019
81b3acd
Re-word to be consistent with other docs
RustyF Mar 3, 2019
28ec527
Ensuring we properly check sub resources
RustyF Mar 4, 2019
2cf1176
Roll-out further use of resource reference check
RustyF Mar 4, 2019
6c6fd64
Fixed path-based rule with redirection test (Path Map test still fail…
RustyF Mar 4, 2019
6a79696
Ensure that optional redirect configuration properties are only set i…
RustyF Mar 6, 2019
57e73e7
Some missing parameters for redirect_configuration use. Plus some pre…
RustyF Mar 6, 2019
0d74b8f
Drop nilOrEmpty() on the basis that it's hardly providing much value/…
RustyF Mar 17, 2019
4598d22
goimports
RustyF Mar 17, 2019
0808922
Merge remote-tracking branch 'remotes/upstream/master' into redirect-…
RustyF Mar 17, 2019
dfa5ca6
Merge branch 'master' into redirect-rules
katbyte Mar 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 235 additions & 2 deletions azurerm/resource_arm_application_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package azurerm

import (
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-08-01/network"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
Expand All @@ -12,6 +10,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
"log"
RustyF marked this conversation as resolved.
Show resolved Hide resolved
)

func resourceArmApplicationGateway() *schema.Resource {
Expand Down Expand Up @@ -420,6 +419,11 @@ func resourceArmApplicationGateway() *schema.Resource {
Optional: true,
},

"redirect_configuration_name": {
Type: schema.TypeString,
Optional: true,
},

"backend_address_pool_id": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -444,6 +448,65 @@ func resourceArmApplicationGateway() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},

"redirect_configuration_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"redirect_configuration": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
RustyF marked this conversation as resolved.
Show resolved Hide resolved

"redirect_type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"Permanent",
RustyF marked this conversation as resolved.
Show resolved Hide resolved
"Temporary",
"Found",
"SeeOther",
}, true),
RustyF marked this conversation as resolved.
Show resolved Hide resolved
},

"target_listener_name": {
Type: schema.TypeString,
Required: true,
},
RustyF marked this conversation as resolved.
Show resolved Hide resolved

"target_url": {
Type: schema.TypeString,
Optional: true,
},

"include_path": {
Type: schema.TypeBool,
Optional: true,
},

"include_query_string": {
Type: schema.TypeBool,
Optional: true,
},

"id": {
Type: schema.TypeString,
Computed: true,
},

"target_listener_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
Expand Down Expand Up @@ -681,6 +744,11 @@ func resourceArmApplicationGateway() *schema.Resource {
Required: true,
},

"default_redirect_configuration_name": {
Type: schema.TypeString,
Optional: true,
},

"path_rule": {
Type: schema.TypeList,
Required: true,
Expand Down Expand Up @@ -719,6 +787,11 @@ func resourceArmApplicationGateway() *schema.Resource {
Computed: true,
},

"redirect_configuration_id": {
Type: schema.TypeString,
Computed: true,
},

"id": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -737,6 +810,11 @@ func resourceArmApplicationGateway() *schema.Resource {
Computed: true,
},

"default_redirect_configuration_id": {
Type: schema.TypeString,
Computed: true,
},

"id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -861,6 +939,7 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte
httpListeners := expandApplicationGatewayHTTPListeners(d, gatewayID)
probes := expandApplicationGatewayProbes(d)
requestRoutingRules := expandApplicationGatewayRequestRoutingRules(d, gatewayID)
redirectConfigurations := expandApplicationGatewayRedirectConfigurations(d, gatewayID)
sku := expandApplicationGatewaySku(d)
sslCertificates := expandApplicationGatewaySslCertificates(d)
sslPolicy := expandApplicationGatewaySslPolicy(d)
Expand All @@ -882,6 +961,7 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte
HTTPListeners: httpListeners,
Probes: probes,
RequestRoutingRules: requestRoutingRules,
RedirectConfigurations: redirectConfigurations,
Sku: sku,
SslCertificates: sslCertificates,
SslPolicy: sslPolicy,
Expand Down Expand Up @@ -1014,6 +1094,14 @@ func resourceArmApplicationGatewayRead(d *schema.ResourceData, meta interface{})
return fmt.Errorf("Error setting `request_routing_rule`: %+v", setErr)
}

redirectConfigurations, err := flattenApplicationGatewayRedirectConfigurations(props.RedirectConfigurations)
if err != nil {
return fmt.Errorf("Error flattening `redirect configuration`: %+v", err)
}
if setErr := d.Set("redirect_configuration", redirectConfigurations); setErr != nil {
return fmt.Errorf("Error setting `redirect configuration`: %+v", setErr)
}

if setErr := d.Set("sku", flattenApplicationGatewaySku(props.Sku)); setErr != nil {
return fmt.Errorf("Error setting `sku`: %+v", setErr)
}
Expand Down Expand Up @@ -1850,6 +1938,13 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway
}
}

if redirectConfigName := v["redirect_configuration_name"].(string); redirectConfigName != "" {
redirectConfigID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, redirectConfigName)
rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.RedirectConfiguration = &network.SubResource{
ID: utils.String(redirectConfigID),
}
}

results = append(results, rule)
}

Expand Down Expand Up @@ -1925,6 +2020,112 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa
}
}

if redirect := props.RedirectConfiguration; redirect != nil {
if redirect.ID != nil {
redirectId, err := parseAzureResourceID(*redirect.ID)
if err != nil {
return nil, err
}
redirectName := redirectId.Path["redirectConfigurations"]
output["redirect_configuration_name"] = redirectName
output["redirect_configuration_id"] = *redirect.ID
}
}

results = append(results, output)
}
}

return results, nil
}

func expandApplicationGatewayRedirectConfigurations(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayRedirectConfiguration {

vs := d.Get("redirect_configuration").([]interface{})
results := make([]network.ApplicationGatewayRedirectConfiguration, 0)

for _, raw := range vs {
v := raw.(map[string]interface{})

name := v["name"].(string)
redirectType := v["redirect_type"].(string)

targetListenerName := v["target_listener_name"].(string)
targetListenerID := fmt.Sprintf("%s/httpListeners/%s", gatewayID, targetListenerName)

targetUrl := v["target_url"].(string)

includePath := v["include_path"].(bool)
includeQueryString := v["include_query_string"].(bool)

output := network.ApplicationGatewayRedirectConfiguration{
Name: utils.String(name),
ApplicationGatewayRedirectConfigurationPropertiesFormat: &network.ApplicationGatewayRedirectConfigurationPropertiesFormat{
RedirectType: network.ApplicationGatewayRedirectType(redirectType),

TargetListener: &network.SubResource{
ID: utils.String(targetListenerID),
},
TargetURL: utils.String(targetUrl),

IncludePath: utils.Bool(includePath),
IncludeQueryString: utils.Bool(includeQueryString),
},
}

results = append(results, output)
}

return &results
}

func flattenApplicationGatewayRedirectConfigurations(input *[]network.ApplicationGatewayRedirectConfiguration) ([]interface{}, error) {
results := make([]interface{}, 0)
if input == nil {
return results, nil
}

for _, config := range *input {
if props := config.ApplicationGatewayRedirectConfigurationPropertiesFormat; props != nil {

output := map[string]interface{}{
"redirect_type": string(props.RedirectType),
}

if config.ID != nil {
output["id"] = *config.ID
}

if config.Name != nil {
output["name"] = *config.Name
}

if listener := props.TargetListener; listener != nil {
if listener.ID != nil {
listenerId, err := parseAzureResourceID(*listener.ID)
if err != nil {
return nil, err
}
targetListenerName := listenerId.Path["httpListeners"]
output["target_listener_name"] = targetListenerName
output["target_listener_id"] = *listener.ID
}
}

if config.TargetURL != nil {
output["target_url"] = *config.TargetURL
}

if config.IncludePath != nil {
output["include_path"] = *config.IncludePath
}

if config.IncludeQueryString != nil {
output["include_query_string"] = *config.IncludeQueryString
}

// TODO: Do we need/want to return the collections of referencing []SubResource ?

results = append(results, output)
}
}
Expand Down Expand Up @@ -2049,9 +2250,11 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
name := v["name"].(string)
defaultBackendAddressPoolName := v["default_backend_address_pool_name"].(string)
defaultBackendHTTPSettingsName := v["default_backend_http_settings_name"].(string)
defaultRedirectConfigurationName := v["default_redirect_configuration_name"].(string)

defaultBackendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, defaultBackendAddressPoolName)
defaultBackendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, defaultBackendHTTPSettingsName)
defaultRedirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, defaultRedirectConfigurationName)

pathRules := make([]network.ApplicationGatewayPathRule, 0)
for _, ruleConfig := range v["path_rule"].([]interface{}) {
Expand Down Expand Up @@ -2085,6 +2288,13 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
}
}

if redirectConfigurationName := ruleConfigMap["redirect_configuration_name"].(string); redirectConfigurationName != "" {
redirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, redirectConfigurationName)
rule.ApplicationGatewayPathRulePropertiesFormat.RedirectConfiguration = &network.SubResource{
ID: utils.String(redirectConfigurationID),
}
}

pathRules = append(pathRules, rule)
}

Expand All @@ -2097,6 +2307,9 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
DefaultBackendHTTPSettings: &network.SubResource{
ID: utils.String(defaultBackendHTTPSettingsID),
},
DefaultRedirectConfiguration: &network.SubResource{
ID: utils.String(defaultRedirectConfigurationID),
},
RustyF marked this conversation as resolved.
Show resolved Hide resolved
PathRules: &pathRules,
},
}
Expand Down Expand Up @@ -2145,6 +2358,16 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL
output["default_backend_http_settings_id"] = *settings.ID
}

if redirect := props.DefaultRedirectConfiguration; redirect != nil && redirect.ID != nil {
settingsId, err := parseAzureResourceID(*redirect.ID)
if err != nil {
return nil, err
}
redirectConfigurationName := settingsId.Path["redirectConfigurations"]
output["default_redirect_configuration_name"] = redirectConfigurationName
output["default_redirect_configuration_id"] = *redirect.ID
}

pathRules := make([]interface{}, 0)
if rules := props.PathRules; rules != nil {
for _, rule := range *rules {
Expand Down Expand Up @@ -2179,6 +2402,16 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL
ruleOutput["backend_http_settings_id"] = *backend.ID
}

if redirect := ruleProps.RedirectConfiguration; redirect != nil && redirect.ID != nil {
redirectId, err := parseAzureResourceID(*redirect.ID)
if err != nil {
return nil, err
}
redirectConfigurationName := redirectId.Path["redirectConfigurations"]
ruleOutput["redirect_configuration_name"] = redirectConfigurationName
ruleOutput["redirect_configuration_id"] = *redirect.ID
}

pathOutputs := make([]interface{}, 0)
if paths := ruleProps.Paths; paths != nil {
for _, rulePath := range *paths {
Expand Down
Loading