aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xscripts/make_layer_zip.sh8
-rw-r--r--src/extract_lambda.py1
-rw-r--r--terraform/iam.tf17
-rw-r--r--terraform/lambda.tf22
-rw-r--r--terraform/s3.tf5
-rw-r--r--test/test_secrets_manager.py39
-rw-r--r--tests/test_extract_lambda.py34
7 files changed, 49 insertions, 77 deletions
diff --git a/scripts/make_layer_zip.sh b/scripts/make_layer_zip.sh
new file mode 100755
index 0000000..eabe301
--- /dev/null
+++ b/scripts/make_layer_zip.sh
@@ -0,0 +1,8 @@
+# Description: Make the zip file for the layer
+
+cd "$(dirname "$0")/.."
+mkdir -p python/lib/python3.11/site-packages
+pip3 install --upgrade -r requirements.txt -t python/lib/python3.11/site-packages
+rm layer.zip
+zip -r layer.zip python
+rm -r python/
diff --git a/src/extract_lambda.py b/src/extract_lambda.py
index 9b17ef2..15fe785 100644
--- a/src/extract_lambda.py
+++ b/src/extract_lambda.py
@@ -90,6 +90,7 @@ def extract_bucket(client=boto3.client("s3")):
extract_bucket_filter = [
bucket["Name"] for bucket in response["Buckets"] if "extract" in bucket["Name"]
]
+
return extract_bucket_filter[0]
diff --git a/terraform/iam.tf b/terraform/iam.tf
index 0e5fa6d..7585ff8 100644
--- a/terraform/iam.tf
+++ b/terraform/iam.tf
@@ -28,17 +28,19 @@ resource "aws_iam_role" "multi_service_role" {
########################################################################
# S3 SETUP
# Description: allows allows retention/tagging/access control settings
-# Lambda IAM Policy for S3 Write
+# Lambda IAM Policy for S3
########################################################################
# S3 DEFINE POLICY
data "aws_iam_policy_document" "s3_data_policy_doc" {
statement {
+ effect = "Allow"
actions = [
"s3:PutObject",
"s3:PutObjectRetention",
"s3:PutObjectTagging",
- "s3:PutObjectAcl"
+ "s3:PutObjectAcl",
+ "s3:ListObjects"
]
resources = [
"${aws_s3_bucket.extract_bucket.arn}/*",
@@ -46,6 +48,17 @@ data "aws_iam_policy_document" "s3_data_policy_doc" {
"${aws_s3_bucket.lambda_code_bucket.arn}/*",
]
}
+
+ statement {
+ effect = "Allow"
+ actions = [
+ "s3:ListBuckets",
+ "s3:ListAllMyBuckets"
+ ]
+ resources = [
+ "arn:aws:s3:::*",
+ ]
+ }
}
diff --git a/terraform/lambda.tf b/terraform/lambda.tf
index e33bc79..72aae04 100644
--- a/terraform/lambda.tf
+++ b/terraform/lambda.tf
@@ -90,27 +90,21 @@ resource "aws_lambda_function" "load_lambda" {
# Lambda Layer Specification
locals {
- layer_dir = "lambda_layer"
- requirements = "requirements.txt"
- layer_zip = "layer.zip"
- layer_name = "lambda_layer_dev"
+ layer_dir = "../"
+ layer_zip = "layer.zip"
+ layer_name = "lambda_layer"
+ script_dir = "../scripts"
}
resource "null_resource" "prepare_layer" {
provisioner "local-exec" {
- command = <<EOT
- cd ${local.layer_dir}
- rm -rf python
- mkdir python
- pip3 install -r ${local.requirements} -t python/
- zip -r ${local.layer_zip} python
- EOT
- } #removed / at the end of python in line 99
+ command = "bash ${local.script_dir}/make_layer_zip.sh"
+ }
}
resource "aws_s3_object" "lambda_layer_zip" {
bucket = aws_s3_bucket.lambda_code_bucket.id #bucket instead of id
- key = "lambda_layer/${local.layer_name}/${local.layer_zip}"
+ key = "${local.layer_name}/${local.layer_zip}"
source = "${local.layer_dir}/${local.layer_zip}"
depends_on = [null_resource.prepare_layer]
}
@@ -118,7 +112,7 @@ resource "aws_s3_object" "lambda_layer_zip" {
resource "aws_lambda_layer_version" "lambda_layer" {
layer_name = local.layer_name
compatible_runtimes = ["python3.11"]
- s3_bucket = aws_s3_bucket.lambda_layer_bucket.id #bucket instead of id
+ s3_bucket = aws_s3_bucket.lambda_code_bucket.bucket
s3_key = aws_s3_object.lambda_layer_zip.key
skip_destroy = true
depends_on = [aws_s3_object.lambda_layer_zip]
diff --git a/terraform/s3.tf b/terraform/s3.tf
index b3a863c..d5cdee3 100644
--- a/terraform/s3.tf
+++ b/terraform/s3.tf
@@ -12,8 +12,3 @@ resource "aws_s3_bucket" "transform_bucket" {
resource "aws_s3_bucket" "lambda_code_bucket" {
bucket_prefix = "${var.s3_code_bucket_name}-"
}
-
-### LAMBDA LAYER BUCKET
-resource "aws_s3_bucket" "lambda_layer_bucket" {
- bucket_prefix = "lambda-layer-dev-"
-} \ No newline at end of file
diff --git a/test/test_secrets_manager.py b/test/test_secrets_manager.py
deleted file mode 100644
index cb4ec15..0000000
--- a/test/test_secrets_manager.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from src.secrets_manager import sm_client, create_secret, list_secret
-import boto3
-from moto import mock_aws
-import json
-import pytest
-import os
-
-pytest.fixture(scope="class")
-
-
-def mock_aws_credentials():
- """Mocked AWS Credentials for moto."""
- os.environ["AWS_ACCESS_KEY_ID"] = "testing"
- os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
- os.environ["AWS_SECURITY_TOKEN"] = "testing"
- os.environ["AWS_SESSION_TOKEN"] = "testing"
- os.environ["AWS_DEFAULT_REGION"] = "eu-west-2"
-
-
-@pytest.fixture(scope="class")
-def mock_sm_client(mock_aws_credentials):
- with mock_aws():
- yield boto3.client("secretsmanager")
-
-
-def test_create_secret_stores_secrets(mock_sm_client):
- cohort_id = "test_cohort_id"
- user = "test_user_id"
- password = "test_password"
- host = "test_host"
- database = "test_database"
- port = "test_port"
-
- secret_name = "test_secret"
- response = create_secret(
- mock_sm_client, secret_name, cohort_id, user, password, host, database, port
- )
-
- assert response["Name"] == secret_name
diff --git a/tests/test_extract_lambda.py b/tests/test_extract_lambda.py
index 5a1c5b2..347ef22 100644
--- a/tests/test_extract_lambda.py
+++ b/tests/test_extract_lambda.py
@@ -1,3 +1,5 @@
+import boto3.exceptions
+import botocore.exceptions
import pytest
import boto3
from moto import mock_aws
@@ -35,7 +37,7 @@ def mock_config():
def aws_credentials():
os.environ["AWS_ACCESS_KEY_ID"] = "testing"
os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
- os.environ["AWS_SECURIT_TOKEN"] = "testing"
+ os.environ["AWS_SECURITY_TOKEN"] = "testing"
os.environ["AWS_SESSION_TOKEN"] = "testing"
os.environ["AWS_DEFAULT_REGION"] = "eu-west-2"
@@ -46,6 +48,15 @@ def s3_client(aws_credentials):
yield boto3.client("s3")
+@pytest.fixture(scope="class")
+def s3_mock_bucket(s3_client):
+ bucket = s3_client.create_bucket(
+ Bucket="extract_bucket",
+ CreateBucketConfiguration={"LocationConstraint": "eu-west-2"},
+ )
+ return bucket
+
+
class TestLambdaHandler:
def test_lambda_handler_files_processed_and_uploaded_successfully(self, mocker):
mock_db = MagicMock()
@@ -138,27 +149,18 @@ class TestListExistingS3Files:
list_existing_s3_files(client=s3_client)
assert "Error listing S3 objects" in caplog.text
- def test_error_if_bucket_is_empty(self, s3_client, caplog):
- s3_client.create_bucket(
- Bucket="extract_bucket",
- CreateBucketConfiguration={"LocationConstraint": "eu-west-2"},
- )
+ def test_error_if_bucket_is_empty(self, s3_client, caplog, s3_mock_bucket):
list_existing_s3_files("extract_bucket", client=s3_client)
assert "The bucket is empty" in caplog.text
- def test_error_retrieving_object(self, s3_client, caplog):
+ def test_retrieves_file_content(self, s3_client, caplog, s3_mock_bucket):
s3_client.upload_file("tests/dummy.txt", "extract_bucket", "dummy.txt")
- list_existing_s3_files(bucket_name="test_bucket", client=s3_client)
-
- assert "Error retrieving S3 object " in caplog.text
-
- def test_retrieves_file_content(self, s3_client, caplog):
- result = list_existing_s3_files(client=s3_client)
-
+ result = list_existing_s3_files("extract_bucket", client=s3_client)
assert list(result.values()) == ["This is a test file."]
class TestConnectToDatabase:
+ # had mock_config in param
def test_connect_to_database(mock_conn, mock_config):
with patch("src.extract_lambda.Connection", autospec=True) as mock_conn:
connect_to_database()
@@ -166,7 +168,7 @@ class TestConnectToDatabase:
host="abc", user="def", port="5432", password="password", database="db"
)
- def test_database_error(self, mock_config):
+ def test_database_error(self, mock_config): # had mock_config in param
with pytest.raises(DBConnectionException):
connect_to_database()
@@ -178,7 +180,6 @@ class TestConnectToDatabase:
connect_to_database()
assert "Interface error" in caplog.text
-
class TestProcessAndUploadTables:
def test_error_process_and_upload_tables(mock_conn, s3_client, caplog):
caplog.set_level(logging.INFO)
@@ -218,4 +219,3 @@ class TestProcessAndUploadTables:
# Assert that the log contains "No new data"
assert "No new data" in caplog.text
- # process and upload tables needs more tests
git.ajschof.me — hosted by ajschofield — powered by cgit