Skip to content

Commit

Permalink
Application Gateway: Moved validations from flatten to expand (#3340)
Browse files Browse the repository at this point in the history
Fixes #3338
  • Loading branch information
mcharriere authored and katbyte committed May 10, 2019
1 parent d2edc8e commit 1017878
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 67 deletions.
154 changes: 88 additions & 66 deletions azurerm/resource_arm_application_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,13 @@ func resourceArmApplicationGateway() *schema.Resource {
"include_path": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

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

"id": {
Expand Down Expand Up @@ -1089,16 +1091,28 @@ func resourceArmApplicationGatewayCreateUpdate(d *schema.ResourceData, meta inte
gatewayIPConfigurations := expandApplicationGatewayIPConfigurations(d)
httpListeners := expandApplicationGatewayHTTPListeners(d, gatewayID)
probes := expandApplicationGatewayProbes(d)
requestRoutingRules := expandApplicationGatewayRequestRoutingRules(d, gatewayID)
redirectConfigurations := expandApplicationGatewayRedirectConfigurations(d, gatewayID)
sku := expandApplicationGatewaySku(d)
autoscaleConfiguration := expandApplicationGatewayAutoscaleConfiguration(d)
sslCertificates := expandApplicationGatewaySslCertificates(d)
sslPolicy := expandApplicationGatewaySslPolicy(d)
customErrorConfigurations := expandApplicationGatewayCustomErrorConfigurations(d.Get("custom_error_configuration").([]interface{}))
urlPathMaps := expandApplicationGatewayURLPathMaps(d, gatewayID)
zones := expandZones(d.Get("zones").([]interface{}))

requestRoutingRules, err := expandApplicationGatewayRequestRoutingRules(d, gatewayID)
if err != nil {
return fmt.Errorf("Error expanding `request_routing_rule`: %+v", err)
}

urlPathMaps, err := expandApplicationGatewayURLPathMaps(d, gatewayID)
if err != nil {
return fmt.Errorf("Error expanding `url_path_map`: %+v", err)
}

redirectConfigurations, err := expandApplicationGatewayRedirectConfigurations(d, gatewayID)
if err != nil {
return fmt.Errorf("Error expanding `redirect_configuration`: %+v", err)
}

gateway := network.ApplicationGateway{
Location: utils.String(location),
Zones: zones,
Expand Down Expand Up @@ -2121,7 +2135,7 @@ func flattenApplicationGatewayProbes(input *[]network.ApplicationGatewayProbe) [
return results
}

func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayRequestRoutingRule {
func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayRequestRoutingRule, error) {
vs := d.Get("request_routing_rule").([]interface{})
results := make([]network.ApplicationGatewayRequestRoutingRule, 0)

Expand All @@ -2132,6 +2146,9 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway
ruleType := v["rule_type"].(string)
httpListenerName := v["http_listener_name"].(string)
httpListenerID := fmt.Sprintf("%s/httpListeners/%s", gatewayID, httpListenerName)
backendAddressPoolName := v["backend_address_pool_name"].(string)
backendHTTPSettingsName := v["backend_http_settings_name"].(string)
redirectConfigName := v["redirect_configuration_name"].(string)

rule := network.ApplicationGatewayRequestRoutingRule{
Name: utils.String(name),
Expand All @@ -2143,38 +2160,46 @@ func expandApplicationGatewayRequestRoutingRules(d *schema.ResourceData, gateway
},
}

if backendAddressPoolName := v["backend_address_pool_name"].(string); backendAddressPoolName != "" {
if backendAddressPoolName != "" && redirectConfigName != "" {
return nil, fmt.Errorf("Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)")
}

if backendHTTPSettingsName != "" && redirectConfigName != "" {
return nil, fmt.Errorf("Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)")
}

if backendAddressPoolName != "" {
backendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, backendAddressPoolName)
rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.BackendAddressPool = &network.SubResource{
ID: utils.String(backendAddressPoolID),
}
}

if backendHTTPSettingsName := v["backend_http_settings_name"].(string); backendHTTPSettingsName != "" {
if backendHTTPSettingsName != "" {
backendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, backendHTTPSettingsName)
rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.BackendHTTPSettings = &network.SubResource{
ID: utils.String(backendHTTPSettingsID),
}
}

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

if urlPathMapName := v["url_path_map_name"].(string); urlPathMapName != "" {
urlPathMapID := fmt.Sprintf("%s/urlPathMaps/%s", gatewayID, urlPathMapName)
rule.ApplicationGatewayRequestRoutingRulePropertiesFormat.URLPathMap = &network.SubResource{
ID: utils.String(urlPathMapID),
}
}

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)
}

return &results
return &results, nil
}

func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGatewayRequestRoutingRule) ([]interface{}, error) {
Expand All @@ -2186,14 +2211,6 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa
for _, config := range *input {
if props := config.ApplicationGatewayRequestRoutingRulePropertiesFormat; props != nil {

if applicationGatewayHasSubResource(props.BackendAddressPool) && applicationGatewayHasSubResource(props.RedirectConfiguration) {
return nil, fmt.Errorf("[ERROR] Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)")
}

if applicationGatewayHasSubResource(props.BackendHTTPSettings) && applicationGatewayHasSubResource(props.RedirectConfiguration) {
return nil, fmt.Errorf("[ERROR] Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)")
}

output := map[string]interface{}{
"rule_type": string(props.RuleType),
}
Expand Down Expand Up @@ -2273,11 +2290,7 @@ func flattenApplicationGatewayRequestRoutingRules(input *[]network.ApplicationGa
return results, nil
}

func applicationGatewayHasSubResource(subResource *network.SubResource) bool {
return subResource != nil && subResource.ID != nil && *subResource.ID != ""
}

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

vs := d.Get("redirect_configuration").([]interface{})
results := make([]network.ApplicationGatewayRedirectConfiguration, 0)
Expand All @@ -2287,37 +2300,47 @@ func expandApplicationGatewayRedirectConfigurations(d *schema.ResourceData, gate

name := v["name"].(string)
redirectType := v["redirect_type"].(string)
targetListenerName := v["target_listener_name"].(string)
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),
RedirectType: network.ApplicationGatewayRedirectType(redirectType),
IncludeQueryString: utils.Bool(includeQueryString),
},
}

if includePath := v["include_path"].(bool); includePath {
output.ApplicationGatewayRedirectConfigurationPropertiesFormat.IncludePath = utils.Bool(includePath)
if targetListenerName == "" && targetUrl == "" {
return nil, fmt.Errorf("Set either `target_listener_name` or `target_url`")
}

if targetListenerName != "" && targetUrl != "" {
return nil, fmt.Errorf("Conflict between `target_listener_name` and `target_url` (redirection is either to URL or target listener)")
}

if includeQueryString := v["include_query_string"].(bool); includeQueryString {
output.ApplicationGatewayRedirectConfigurationPropertiesFormat.IncludeQueryString = utils.Bool(includeQueryString)
if targetUrl != "" && includePath {
return nil, fmt.Errorf("`include_path` is not a valid option when `target_url` is set")
}

if targetListenerName := v["target_listener_name"].(string); targetListenerName != "" {
if targetListenerName != "" {
targetListenerID := fmt.Sprintf("%s/httpListeners/%s", gatewayID, targetListenerName)
output.ApplicationGatewayRedirectConfigurationPropertiesFormat.TargetListener = &network.SubResource{
ID: utils.String(targetListenerID),
}
output.ApplicationGatewayRedirectConfigurationPropertiesFormat.IncludePath = utils.Bool(includePath)
}

if targetUrl := v["target_url"].(string); targetUrl != "" {
if targetUrl != "" {
output.ApplicationGatewayRedirectConfigurationPropertiesFormat.TargetURL = utils.String(targetUrl)
}

results = append(results, output)
}

return &results
return &results, nil
}

func flattenApplicationGatewayRedirectConfigurations(input *[]network.ApplicationGatewayRedirectConfiguration) ([]interface{}, error) {
Expand All @@ -2329,17 +2352,6 @@ func flattenApplicationGatewayRedirectConfigurations(input *[]network.Applicatio
for _, config := range *input {
if props := config.ApplicationGatewayRedirectConfigurationPropertiesFormat; props != nil {

if !applicationGatewayHasSubResource(config.TargetListener) && (config.TargetURL == nil || *config.TargetURL == "") {
return nil, fmt.Errorf("[ERROR] Set either `target_listener_name` or `target_url`")
}
if applicationGatewayHasSubResource(config.TargetListener) && config.TargetURL != nil && *config.TargetURL != "" {
return nil, fmt.Errorf("[ERROR] Conflict between `target_listener_name` and `target_url` (redirection is either to URL or target listener)")
}

if config.TargetURL != nil && *config.TargetURL != "" && config.IncludePath != nil {
return nil, fmt.Errorf("[ERROR] `include_path` is not a valid option when `target_url` is set")
}

output := map[string]interface{}{
"redirect_type": string(props.RedirectType),
}
Expand Down Expand Up @@ -2531,7 +2543,7 @@ func flattenApplicationGatewaySslCertificates(input *[]network.ApplicationGatewa
return results
}

func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID string) *[]network.ApplicationGatewayURLPathMap {
func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID string) (*[]network.ApplicationGatewayURLPathMap, error) {
vs := d.Get("url_path_map").([]interface{})
results := make([]network.ApplicationGatewayURLPathMap, 0)

Expand All @@ -2545,6 +2557,9 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
ruleConfigMap := ruleConfig.(map[string]interface{})

ruleName := ruleConfigMap["name"].(string)
backendAddressPoolName := ruleConfigMap["backend_address_pool_name"].(string)
backendHTTPSettingsName := ruleConfigMap["backend_http_settings_name"].(string)
redirectConfigurationName := ruleConfigMap["redirect_configuration_name"].(string)

rulePaths := make([]string, 0)
for _, rulePath := range ruleConfigMap["paths"].([]interface{}) {
Expand All @@ -2558,21 +2573,29 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
},
}

if backendAddressPoolName := ruleConfigMap["backend_address_pool_name"].(string); backendAddressPoolName != "" {
if backendAddressPoolName != "" && redirectConfigurationName != "" {
return nil, fmt.Errorf("Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)")
}

if backendHTTPSettingsName != "" && redirectConfigurationName != "" {
return nil, fmt.Errorf("Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)")
}

if backendAddressPoolName != "" {
backendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, backendAddressPoolName)
rule.ApplicationGatewayPathRulePropertiesFormat.BackendAddressPool = &network.SubResource{
ID: utils.String(backendAddressPoolID),
}
}

if backendHTTPSettingsName := ruleConfigMap["backend_http_settings_name"].(string); backendHTTPSettingsName != "" {
if backendHTTPSettingsName != "" {
backendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, backendHTTPSettingsName)
rule.ApplicationGatewayPathRulePropertiesFormat.BackendHTTPSettings = &network.SubResource{
ID: utils.String(backendHTTPSettingsID),
}
}

if redirectConfigurationName := ruleConfigMap["redirect_configuration_name"].(string); redirectConfigurationName != "" {
if redirectConfigurationName != "" {
redirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, redirectConfigurationName)
rule.ApplicationGatewayPathRulePropertiesFormat.RedirectConfiguration = &network.SubResource{
ID: utils.String(redirectConfigurationID),
Expand All @@ -2589,25 +2612,33 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
},
}

// treating these three as optional as seems necessary when redirection is also an alternative. Not explicit in the documentation, though
// see https://docs.microsoft.com/en-us/rest/api/application-gateway/applicationgateways/createorupdate#applicationgatewayurlpathmap
// see also az docs https://docs.microsoft.com/en-us/cli/azure/network/application-gateway/url-path-map?view=azure-cli-latest#az-network-application-gateway-url-path-map-create
defaultBackendAddressPoolName := v["default_backend_address_pool_name"].(string)
defaultBackendHTTPSettingsName := v["default_backend_http_settings_name"].(string)
defaultRedirectConfigurationName := v["default_redirect_configuration_name"].(string)

if defaultBackendAddressPoolName != "" && defaultRedirectConfigurationName != "" {
return nil, fmt.Errorf("Conflict between `default_backend_address_pool_name` and `default_redirect_configuration_name` (back-end pool not applicable when redirection specified)")
}

if defaultBackendHTTPSettingsName != "" && defaultRedirectConfigurationName != "" {
return nil, fmt.Errorf("Conflict between `default_backend_http_settings_name` and `default_redirect_configuration_name` (back-end settings not applicable when redirection specified)")
}

if defaultBackendAddressPoolName := v["default_backend_address_pool_name"].(string); defaultBackendAddressPoolName != "" {
if defaultBackendAddressPoolName != "" {
defaultBackendAddressPoolID := fmt.Sprintf("%s/backendAddressPools/%s", gatewayID, defaultBackendAddressPoolName)
output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultBackendAddressPool = &network.SubResource{
ID: utils.String(defaultBackendAddressPoolID),
}
}

if defaultBackendHTTPSettingsName := v["default_backend_http_settings_name"].(string); defaultBackendHTTPSettingsName != "" {
if defaultBackendHTTPSettingsName != "" {
defaultBackendHTTPSettingsID := fmt.Sprintf("%s/backendHttpSettingsCollection/%s", gatewayID, defaultBackendHTTPSettingsName)
output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultBackendHTTPSettings = &network.SubResource{
ID: utils.String(defaultBackendHTTPSettingsID),
}
}

if defaultRedirectConfigurationName := v["default_redirect_configuration_name"].(string); defaultRedirectConfigurationName != "" {
if defaultRedirectConfigurationName != "" {
defaultRedirectConfigurationID := fmt.Sprintf("%s/redirectConfigurations/%s", gatewayID, defaultRedirectConfigurationName)
output.ApplicationGatewayURLPathMapPropertiesFormat.DefaultRedirectConfiguration = &network.SubResource{
ID: utils.String(defaultRedirectConfigurationID),
Expand All @@ -2617,7 +2648,7 @@ func expandApplicationGatewayURLPathMaps(d *schema.ResourceData, gatewayID strin
results = append(results, output)
}

return &results
return &results, nil
}

func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURLPathMap) ([]interface{}, error) {
Expand Down Expand Up @@ -2682,15 +2713,6 @@ func flattenApplicationGatewayURLPathMaps(input *[]network.ApplicationGatewayURL
}

if ruleProps := rule.ApplicationGatewayPathRulePropertiesFormat; ruleProps != nil {

if applicationGatewayHasSubResource(ruleProps.BackendAddressPool) && applicationGatewayHasSubResource(ruleProps.RedirectConfiguration) {
return nil, fmt.Errorf("[ERROR] Conflict between `backend_address_pool_name` and `redirect_configuration_name` (back-end pool not applicable when redirection specified)")
}

if applicationGatewayHasSubResource(ruleProps.BackendHTTPSettings) && applicationGatewayHasSubResource(ruleProps.RedirectConfiguration) {
return nil, fmt.Errorf("[ERROR] Conflict between `backend_http_settings_name` and `redirect_configuration_name` (back-end settings not applicable when redirection specified)")
}

if pool := ruleProps.BackendAddressPool; pool != nil && pool.ID != nil {
poolId, err := parseAzureResourceID(*pool.ID)
if err != nil {
Expand Down
Loading

0 comments on commit 1017878

Please sign in to comment.