Validate elbv2 FixedResponseConfig attributes

This commit is contained in:
Jessie Nadler 2019-09-12 12:29:03 -04:00
parent 2983a63c0d
commit 2b8bdc9bca
3 changed files with 186 additions and 4 deletions

View File

@ -190,3 +190,18 @@ class InvalidModifyRuleArgumentsError(ELBClientError):
"ValidationError", "ValidationError",
"Either conditions or actions must be specified" "Either conditions or actions must be specified"
) )
class InvalidStatusCodeActionTypeError(ELBClientError):
def __init__(self, msg):
super(InvalidStatusCodeActionTypeError, self).__init__(
"ValidationError", msg
)
class InvalidLoadBalancerActionException(ELBClientError):
def __init__(self, msg):
super(InvalidLoadBalancerActionException, self).__init__(
"InvalidLoadBalancerAction", msg
)

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
import datetime import datetime
import re import re
from jinja2 import Template from jinja2 import Template
from botocore.exceptions import ParamValidationError
from moto.compat import OrderedDict from moto.compat import OrderedDict
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
@ -31,8 +32,8 @@ from .exceptions import (
RuleNotFoundError, RuleNotFoundError,
DuplicatePriorityError, DuplicatePriorityError,
InvalidTargetGroupNameError, InvalidTargetGroupNameError,
InvalidModifyRuleArgumentsError InvalidModifyRuleArgumentsError,
) InvalidStatusCodeActionTypeError, InvalidLoadBalancerActionException)
class FakeHealthStatus(BaseModel): class FakeHealthStatus(BaseModel):
@ -488,11 +489,30 @@ class ELBv2Backend(BaseBackend):
action_target_group_arn = action.data['target_group_arn'] action_target_group_arn = action.data['target_group_arn']
if action_target_group_arn not in target_group_arns: if action_target_group_arn not in target_group_arns:
raise ActionTargetGroupNotFoundError(action_target_group_arn) raise ActionTargetGroupNotFoundError(action_target_group_arn)
elif action_type in ['redirect', 'authenticate-cognito', 'fixed-response']: elif action_type == 'fixed-response':
self._validate_fixed_response_action(action, i, index)
elif action_type in ['redirect', 'authenticate-cognito']:
pass pass
else: else:
raise InvalidActionTypeError(action_type, index) raise InvalidActionTypeError(action_type, index)
def _validate_fixed_response_action(self, action, i, index):
status_code = action.data.get('fixed_response_config._status_code')
if status_code is None:
raise ParamValidationError(
report='Missing required parameter in Actions[%s].FixedResponseConfig: "StatusCode"' % i)
if not re.match(r'^(2|4|5)\d\d$', status_code):
raise InvalidStatusCodeActionTypeError(
"1 validation error detected: Value '%s' at 'actions.%s.member.fixedResponseConfig.statusCode' failed to satisfy constraint: \
Member must satisfy regular expression pattern: ^(2|4|5)\d\d$" % (status_code, index)
)
content_type = action.data['fixed_response_config._content_type']
if content_type and content_type not in ['text/plain', 'text/css', 'text/html', 'application/javascript',
'application/json']:
raise InvalidLoadBalancerActionException(
"The ContentType must be one of:'text/html', 'application/json', 'application/javascript', 'text/css', 'text/plain'"
)
def create_target_group(self, name, **kwargs): def create_target_group(self, name, **kwargs):
if len(name) > 32: if len(name) > 32:
raise InvalidTargetGroupNameError( raise InvalidTargetGroupNameError(

View File

@ -4,7 +4,7 @@ import json
import os import os
import boto3 import boto3
import botocore import botocore
from botocore.exceptions import ClientError from botocore.exceptions import ClientError, ParamValidationError
from nose.tools import assert_raises from nose.tools import assert_raises
import sure # noqa import sure # noqa
@ -2146,3 +2146,150 @@ def test_fixed_response_action_listener_rule_cloudformation():
'StatusCode': '404', 'StatusCode': '404',
} }
},]) },])
@mock_elbv2
@mock_ec2
def test_fixed_response_action_listener_rule_validates_status_code():
conn = boto3.client('elbv2', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
security_group = ec2.create_security_group(
GroupName='a-security-group', Description='First One')
vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default')
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1a')
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.128/26',
AvailabilityZone='us-east-1b')
response = conn.create_load_balancer(
Name='my-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
Tags=[{'Key': 'key_name', 'Value': 'a_value'}])
load_balancer_arn = response.get('LoadBalancers')[0].get('LoadBalancerArn')
missing_status_code_action = {
'Type': 'fixed-response',
'FixedResponseConfig': {
'ContentType': 'text/plain',
'MessageBody': 'This page does not exist',
}
}
with assert_raises(ParamValidationError):
conn.create_listener(LoadBalancerArn=load_balancer_arn,
Protocol='HTTP',
Port=80,
DefaultActions=[missing_status_code_action])
invalid_status_code_action = {
'Type': 'fixed-response',
'FixedResponseConfig': {
'ContentType': 'text/plain',
'MessageBody': 'This page does not exist',
'StatusCode': '100'
}
}
@mock_elbv2
@mock_ec2
def test_fixed_response_action_listener_rule_validates_status_code():
conn = boto3.client('elbv2', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
security_group = ec2.create_security_group(
GroupName='a-security-group', Description='First One')
vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default')
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1a')
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.128/26',
AvailabilityZone='us-east-1b')
response = conn.create_load_balancer(
Name='my-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
Tags=[{'Key': 'key_name', 'Value': 'a_value'}])
load_balancer_arn = response.get('LoadBalancers')[0].get('LoadBalancerArn')
missing_status_code_action = {
'Type': 'fixed-response',
'FixedResponseConfig': {
'ContentType': 'text/plain',
'MessageBody': 'This page does not exist',
}
}
with assert_raises(ParamValidationError):
conn.create_listener(LoadBalancerArn=load_balancer_arn,
Protocol='HTTP',
Port=80,
DefaultActions=[missing_status_code_action])
invalid_status_code_action = {
'Type': 'fixed-response',
'FixedResponseConfig': {
'ContentType': 'text/plain',
'MessageBody': 'This page does not exist',
'StatusCode': '100'
}
}
with assert_raises(ClientError) as invalid_status_code_exception:
conn.create_listener(LoadBalancerArn=load_balancer_arn,
Protocol='HTTP',
Port=80,
DefaultActions=[invalid_status_code_action])
invalid_status_code_exception.exception.response['Error']['Code'].should.equal('ValidationError')
@mock_elbv2
@mock_ec2
def test_fixed_response_action_listener_rule_validates_content_type():
conn = boto3.client('elbv2', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
security_group = ec2.create_security_group(
GroupName='a-security-group', Description='First One')
vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default')
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1a')
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.128/26',
AvailabilityZone='us-east-1b')
response = conn.create_load_balancer(
Name='my-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
Tags=[{'Key': 'key_name', 'Value': 'a_value'}])
load_balancer_arn = response.get('LoadBalancers')[0].get('LoadBalancerArn')
invalid_content_type_action = {
'Type': 'fixed-response',
'FixedResponseConfig': {
'ContentType': 'Fake content type',
'MessageBody': 'This page does not exist',
'StatusCode': '200'
}
}
with assert_raises(ClientError) as invalid_content_type_exception:
conn.create_listener(LoadBalancerArn=load_balancer_arn,
Protocol='HTTP',
Port=80,
DefaultActions=[invalid_content_type_action])
invalid_content_type_exception.exception.response['Error']['Code'].should.equal('InvalidLoadBalancerAction')