Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 6 additions & 15 deletions config.example.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# A list of perspectives with the format <RIR>.<AWS-Region> TODO link to pages.
perspectives:
- arin.us-east-2
- arin.us-west-2
- ripe.eu-central-1
- ripe.eu-west-2
- apnic.ap-northeast-2
- apnic.ap-southeast-1
- us-east-2
- us-west-2
- eu-central-1
- eu-west-2
- ap-northeast-2
- ap-southeast-1

# The AWS region name for the API gateway and controller.
api-region: us-east-2
Expand All @@ -22,12 +22,3 @@ caa-domains:
# absolute maximum regardless of orchestration parameters in request
# NOT to be interpreted as the default number of attempts (default is 1 unless explicitly set in request)
absolute-max-attempts: 3

# Whether to run in a more permissive mode for development. Allows specification of named perspectives.
# False by default. If true, result should NOT be used for production MPIC.
# TODO align on naming and behavior (and where this kind of flag goes... API request or config here).
diagnostic-mode: false

# Whether to enforce whether two distinct RIR regions must succeed.
# TODO align on whether this flag is valid to even manage.
enforce-distinct-rir-regions: true
24 changes: 7 additions & 17 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def main(raw_args=None):
if file.endswith(".generated.tf"):
os.remove(os.path.join(open_tofu_dir, file))

regions = [perspective.split('.')[1] for perspective in config['perspectives']]
regions = config['perspectives']

# Generate "main.generated.tf" based on main.tf.template.
with open(args.main_tf_template) as stream:
Expand All @@ -80,8 +80,8 @@ def main(raw_args=None):
main_tf_string = main_tf_string.replace("{{perspective-names-list}}", f"\"{perspective_names_list}\"")

# Generate the ARNs list for validators. Note that this is not a list of actual ARN values. It is just a list of ARN names that will be substituted by Open Tofu.
arn_validator_list = "|".join([f"${{aws_lambda_function.mpic_dcv_checker_lambda_{region}.arn}}" for region in regions])
main_tf_string = main_tf_string.replace("{{validator-arns-list}}", f"\"{arn_validator_list}\"")
arn_mpic_dcv_checker_list = "|".join([f"${{aws_lambda_function.mpic_dcv_checker_lambda_{region}.arn}}" for region in regions])
main_tf_string = main_tf_string.replace("{{validator-arns-list}}", f"\"{arn_mpic_dcv_checker_list}\"")

# Generate the ARNs list for CAA resolvers. Note that this is not a list of actual ARN values. It is just a list of ARN names that will be substituted by Open Tofu.
arn_mpic_caa_checker_list = "|".join([f"${{aws_lambda_function.mpic_caa_checker_lambda_{region}.arn}}" for region in regions])
Expand All @@ -90,14 +90,11 @@ def main(raw_args=None):
# Replace default perspective count.
main_tf_string = main_tf_string.replace("{{default-perspective-count}}", f"\"{config['default-perspective-count']}\"")

# Replace absolout max attempt count if present.
# Replace absolute max attempt count if present.
if "absolute-max-attempts" in config:
main_tf_string = main_tf_string.replace("{{absolut-max-attempts-with-key}}", f"absolute_max_attempts = \"{config['absolute-max-attempts']}\"")
main_tf_string = main_tf_string.replace("{{absolute-max-attempts-with-key}}", f"absolute_max_attempts = \"{config['absolute-max-attempts']}\"")
else:
main_tf_string = main_tf_string.replace("{{absolut-max-attempts-with-key}}", "")

# Replace enforce distinct rir regions.
main_tf_string = main_tf_string.replace("{{enforce-distinct-rir-regions}}", f"\"{1 if config['enforce-distinct-rir-regions'] else 0}\"")
main_tf_string = main_tf_string.replace("{{absolute-max-attempts-with-key}}", "")

# Store the secret key for the vantage points hash in an environment variable.
hash_secret = ''.join(secrets.choice(string.ascii_letters) for i in range(20))
Expand Down Expand Up @@ -133,11 +130,7 @@ def main(raw_args=None):
aws_perspective_tf = stream.read()

# Iterate through the different regions specified and produce an output file for each region.
for perspective in config['perspectives']:
split_perspective = perspective.split(".")
region = split_perspective[1]
rir_region = split_perspective[0]

for region in config['perspectives']:
aws_perspective_tf_region = aws_perspective_tf.replace("{{region}}", region)

# Replace the deployment id.
Expand All @@ -149,9 +142,6 @@ def main(raw_args=None):
# Set the source path for the lambda functions.
aws_perspective_tf_region = aws_perspective_tf_region.replace("{{source-path}}", f"{config['source-path']}")

# Set the RIR region to load into env variables.
aws_perspective_tf_region = aws_perspective_tf_region.replace("{{rir-region}}", f"{rir_region}")

if not args.aws_perspective_tf_template.endswith(".tf.template"):
print(f"Error: invalid tf template name: {args.aws_perspective_tf_template}. Make sure all tf template files end in '.tf.template'.")
exit()
Expand Down
6 changes: 0 additions & 6 deletions open-tofu/aws-perspective.tf.template
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,6 @@ resource "aws_lambda_function" "mpic_dcv_checker_lambda_{{region}}" {
layers = [
aws_lambda_layer_version.python311_open_mpic_layer_{{region}}.arn,
]
environment {
variables = {
rir_region = "{{rir-region}}"
}
}
vpc_config {
subnet_ids = [for s in aws_subnet.subnet_private_{{region}} : s.id]
security_group_ids = [for s in aws_default_security_group.default_security_group_{{region}} : s.id]
Expand Down Expand Up @@ -251,7 +246,6 @@ resource "aws_lambda_function" "mpic_caa_checker_lambda_{{region}}" {
environment {
variables = {
default_caa_domains = {{default-caa-domains}}
rir_region = "{{rir-region}}"
}
}
}
5 changes: 2 additions & 3 deletions open-tofu/main.tf.template
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,11 @@ resource "aws_lambda_function" "mpic_coordinator_lambda" {
environment {
variables = {
perspective_names = {{perspective-names-list}}
validator_arns = {{validator-arns-list}}
dcv_arns = {{validator-arns-list}}
caa_arns = {{mpic-caa-checker-arns-list}}
default_perspective_count = {{default-perspective-count}}
enforce_distinct_rir_regions = {{enforce-distinct-rir-regions}}
hash_secret = {{hash-secret}}
{{absolut-max-attempts-with-key}}
{{absolute-max-attempts-with-key}}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"dnspython==2.6.1",
"pydantic==2.8.2",
"aws-lambda-powertools[parser]==3.2.0",
"open-mpic-core==2.2.0",
"open-mpic-core==3.0.0",
]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/aws_lambda_mpic/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.0"
__version__ = "0.3.0"
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from aws_lambda_powertools.utilities.parser import event_parser

from open_mpic_core.common_domain.check_request import CaaCheckRequest
from open_mpic_core.common_domain.remote_perspective import RemotePerspective
from open_mpic_core.mpic_caa_checker.mpic_caa_checker import MpicCaaChecker
import os


class MpicCaaCheckerLambdaHandler:
def __init__(self):
self.perspective = RemotePerspective(rir=os.environ['rir_region'], code=os.environ['AWS_REGION'])
self.perspective_code = os.environ['AWS_REGION']
self.default_caa_domain_list = os.environ['default_caa_domains'].split("|")
self.caa_checker = MpicCaaChecker(self.default_caa_domain_list, self.perspective)
self.caa_checker = MpicCaaChecker(self.default_caa_domain_list, self.perspective_code)

def process_invocation(self, caa_request: CaaCheckRequest):
caa_response = self.caa_checker.check_caa(caa_request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from open_mpic_core.mpic_coordinator.messages.mpic_request_validation_messages import MpicRequestValidationMessages
from open_mpic_core.mpic_coordinator.mpic_coordinator import MpicCoordinator, MpicCoordinatorConfiguration
from open_mpic_core.common_domain.enum.check_type import CheckType
from open_mpic_core.common_domain.remote_perspective import RemotePerspective
from open_mpic_core.mpic_coordinator.domain.remote_perspective import RemotePerspective

import boto3
import os
Expand All @@ -21,10 +21,9 @@ class MpicCoordinatorLambdaHandler:
def __init__(self):
# load environment variables
self.all_target_perspectives = os.environ['perspective_names'].split("|")
self.dcv_arn_list = os.environ['validator_arns'].split("|") # TODO rename to dcv_arns
self.dcv_arn_list = os.environ['dcv_arns'].split("|")
self.caa_arn_list = os.environ['caa_arns'].split("|")
self.default_perspective_count = int(os.environ['default_perspective_count'])
self.enforce_distinct_rir_regions = int(os.environ['enforce_distinct_rir_regions']) == 1 # TODO may not need...
self.global_max_attempts = int(os.environ['absolute_max_attempts']) if 'absolute_max_attempts' in os.environ else None
self.hash_secret = os.environ['hash_secret']

Expand All @@ -33,15 +32,14 @@ def __init__(self):
CheckType.CAA: {self.all_target_perspectives[i]: self.caa_arn_list[i] for i in range(len(self.all_target_perspectives))}
}

all_target_perspective_codes = [target_perspective.split('.')[1] for target_perspective in self.all_target_perspectives]
all_target_perspective_codes = self.all_target_perspectives
all_possible_perspectives_by_code = MpicCoordinatorLambdaHandler.load_aws_region_config()
self.target_perspectives = MpicCoordinatorLambdaHandler.convert_codes_to_remote_perspectives(
all_target_perspective_codes, all_possible_perspectives_by_code)

self.mpic_coordinator_configuration = MpicCoordinatorConfiguration(
self.target_perspectives,
self.default_perspective_count,
self.enforce_distinct_rir_regions,
self.global_max_attempts,
self.hash_secret
)
Expand Down Expand Up @@ -86,7 +84,7 @@ def convert_codes_to_remote_perspectives(perspective_codes: list[str],
def call_remote_perspective(self, perspective: RemotePerspective, check_type: CheckType, check_request: BaseCheckRequest) -> CheckResponse:
# Uses dcv_arn_list, caa_arn_list
client = boto3.client('lambda', perspective.code)
function_name = self.arns_per_perspective_per_check_type[check_type][perspective.rir + "." + perspective.code]
function_name = self.arns_per_perspective_per_check_type[check_type][perspective.code]
response = client.invoke( # AWS Lambda-specific structure
FunctionName=function_name,
InvocationType='RequestResponse',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
from aws_lambda_powertools.utilities.parser import event_parser

from open_mpic_core.common_domain.check_request import DcvCheckRequest
from open_mpic_core.common_domain.remote_perspective import RemotePerspective
from open_mpic_core.mpic_dcv_checker.mpic_dcv_checker import MpicDcvChecker
import os


class MpicDcvCheckerLambdaHandler:
def __init__(self):
self.perspective = RemotePerspective(rir=os.environ['rir_region'], code=os.environ['AWS_REGION'])
self.dcv_checker = MpicDcvChecker(self.perspective)
self.perspective_code = os.environ['AWS_REGION']
self.dcv_checker = MpicDcvChecker(self.perspective_code)

def process_invocation(self, dcv_request_dict: dict):
dcv_request = DcvCheckRequest.model_validate(dcv_request_dict)
def process_invocation(self, dcv_request: DcvCheckRequest):
dcv_response = self.dcv_checker.check_dcv(dcv_request)
status_code = 200
if dcv_response.errors is not None and len(dcv_response.errors) > 0:
Expand Down
11 changes: 5 additions & 6 deletions tests/unit/aws_lambda_mpic/test_mpic_coordinator_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import yaml
from aws_lambda_powertools.utilities.parser.models import APIGatewayProxyEventModel, APIGatewayEventRequestContext, \
APIGatewayEventIdentity
from pydantic import ValidationError, TypeAdapter
from open_mpic_core.mpic_coordinator.domain.remote_perspective import RemotePerspective
from pydantic import TypeAdapter

from open_mpic_core.common_domain.check_request import DcvCheckRequest
from open_mpic_core.common_domain.check_response import DcvCheckResponse
from open_mpic_core.common_domain.enum.check_type import CheckType
from open_mpic_core.common_domain.remote_perspective import RemotePerspective
from open_mpic_core.common_domain.check_response_details import DcvDnsCheckResponseDetails
from open_mpic_core.common_domain.enum.dcv_validation_method import DcvValidationMethod
from open_mpic_core.mpic_coordinator.domain.mpic_orchestration_parameters import MpicEffectiveOrchestrationParameters
Expand All @@ -32,11 +32,10 @@ class TestMpicCoordinatorLambda:
@pytest.fixture(scope='class')
def set_env_variables():
envvars = {
'perspective_names': 'arin.us-east-1|arin.us-west-1|ripe.eu-west-2|ripe.eu-central-2|apnic.ap-northeast-1|apnic.ap-south-2',
'validator_arns': 'arn:aws:acm-pca:us-east-1:123456789012:validator/arin.us-east-1|arn:aws:acm-pca:us-west-1:123456789012:validator/arin.us-west-1|arn:aws:acm-pca:eu-west-2:123456789012:validator/ripe.eu-west-2|arn:aws:acm-pca:eu-central-2:123456789012:validator/ripe.eu-central-2|arn:aws:acm-pca:ap-northeast-1:123456789012:validator/apnic.ap-northeast-1|arn:aws:acm-pca:ap-south-2:123456789012:validator/apnic.ap-south-2',
'caa_arns': 'arn:aws:acm-pca:us-east-1:123456789012:caa/arin.us-east-1|arn:aws:acm-pca:us-west-1:123456789012:caa/arin.us-west-1|arn:aws:acm-pca:eu-west-2:123456789012:caa/ripe.eu-west-2|arn:aws:acm-pca:eu-central-2:123456789012:caa/ripe.eu-central-2|arn:aws:acm-pca:ap-northeast-1:123456789012:caa/apnic.ap-northeast-1|arn:aws:acm-pca:ap-south-2:123456789012:caa/apnic.ap-south-2',
'perspective_names': 'us-east-1|us-west-1|eu-west-2|eu-central-2|ap-northeast-1|ap-south-2',
'dcv_arns': 'arn:aws:acm-pca:us-east-1:123456789012:validator/us-east-1|arn:aws:acm-pca:us-west-1:123456789012:validator/us-west-1|arn:aws:acm-pca:eu-west-2:123456789012:validator/eu-west-2|arn:aws:acm-pca:eu-central-2:123456789012:validator/eu-central-2|arn:aws:acm-pca:ap-northeast-1:123456789012:validator/ap-northeast-1|arn:aws:acm-pca:ap-south-2:123456789012:validator/ap-south-2',
'caa_arns': 'arn:aws:acm-pca:us-east-1:123456789012:caa/us-east-1|arn:aws:acm-pca:us-west-1:123456789012:caa/us-west-1|arn:aws:acm-pca:eu-west-2:123456789012:caa/eu-west-2|arn:aws:acm-pca:eu-central-2:123456789012:caa/eu-central-2|arn:aws:acm-pca:ap-northeast-1:123456789012:caa/ap-northeast-1|arn:aws:acm-pca:ap-south-2:123456789012:caa/ap-south-2',
'default_perspective_count': '3',
'enforce_distinct_rir_regions': '1', # TODO may not need this...
'hash_secret': 'test_secret'
}
with pytest.MonkeyPatch.context() as class_scoped_monkeypatch:
Expand Down
Loading