def handler()

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