in source/idea/idea-administrator/resources/lambda_functions/idea_custom_resource_cluster_endpoints/handler.py [0:0]
def handler(event: dict, context):
logger.info(f'ReceivedEvent: {json.dumps(event)}')
request_type = event.get('RequestType', None)
resource_properties = event.get('ResourceProperties', {})
# a unique name identifying the endpoint
endpoint_name = resource_properties.get('endpoint_name', '__NOT_PROVIDED__')
client = HttpClient()
try:
if endpoint_name is None or endpoint_name == '__NOT_PROVIDED__':
raise ValueError('endpoint_name is required and cannot be empty')
# listener arn
listener_arn = resource_properties.get('listener_arn')
if listener_arn is None:
raise ValueError('listener_arn is required and cannot be empty')
# the module that hosts the web ui will send default_action = True.
# in the default setup, this will be cluster manager
default_action = resource_properties.get('default_action', False)
# a json array structure as per:
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2.html#ElasticLoadBalancingv2.Client.create_rule
conditions = resource_properties.get('conditions', [])
if not default_action:
if conditions is None or len(conditions) == 0:
raise ValueError('conditions[] is required and cannot be empty')
# a json array structure as per:
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2.html#ElasticLoadBalancingv2.Client.create_rule
actions = resource_properties.get('actions', [])
if not default_action:
if actions is None or len(actions) == 0:
raise ValueError('actions[] is required and cannot be empty')
priority_value = resource_properties.get('priority')
priority = -1
if not default_action:
priority = int(priority_value)
if priority <= 0:
raise ValueError('priority must be greater than 0')
# any applicable tags need to added to the listener rules
tags = resource_properties.get('tags', {})
tags['res:EndpointName'] = endpoint_name
resource_tags = []
for key, value in tags.items():
resource_tags.append({
'Key': key,
'Value': value
})
elbv2_client = boto3.client('elbv2')
if default_action:
if request_type in ('Create', 'Update'):
elbv2_client.modify_listener(
ListenerArn=listener_arn,
DefaultActions=actions
)
logger.info('default action modified')
else:
elbv2_client.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[
{
'Type': 'fixed-response',
'FixedResponseConfig': {
'MessageBody': json.dumps({
'success': True,
'message': 'OK'
}),
'StatusCode': '200',
'ContentType': 'application/json'
}
}
]
)
logger.info('default action reset to fixed response')
elif request_type == 'Create':
result = elbv2_client.create_rule(
ListenerArn=listener_arn,
Conditions=conditions,
Priority=priority,
Actions=actions,
Tags=resource_tags
)
rules = result.get('Rules', [])
rule_arn = rules[0].get('RuleArn')
logger.info(f'rule created. rule arn: {rule_arn}')
elif request_type == 'Update':
rule_arn = find_rule_arn(elbv2_client, listener_arn=listener_arn, endpoint_name=endpoint_name)
if rule_arn is not None:
elbv2_client.modify_rule(
RuleArn=rule_arn,
Conditions=conditions,
Actions=actions
)
logger.info(f'rule modified. rule arn: {rule_arn}')
else:
logger.warning('rule not found for target group. rule update skipped.')
elif request_type == 'Delete':
rule_arn = find_rule_arn(elbv2_client, listener_arn=listener_arn, endpoint_name=endpoint_name)
if rule_arn is not None:
elbv2_client.delete_rule(
RuleArn=rule_arn
)
logger.info(f'rule deleted. rule arn: {rule_arn}')
else:
logger.warning('rule could not be deleted. rule arn not found for target group')
client.send_cfn_response(CfnResponse(
context=context,
event=event,
status=CfnResponseStatus.SUCCESS,
data={},
physical_resource_id=endpoint_name
))
except Exception as e:
error_message = f'failed to {request_type} endpoint: {endpoint_name} - {e}'
logger.exception(error_message)
client.send_cfn_response(CfnResponse(
context=context,
event=event,
status=CfnResponseStatus.FAILED,
data={},
physical_resource_id=endpoint_name,
reason=error_message
))
finally:
client.destroy()