Skip to content

Commit 0f4da27

Browse files
authored
Merge branch 'main' into ELI-623
2 parents de46a5f + 3a69fea commit 0f4da27

17 files changed

Lines changed: 576 additions & 82 deletions

File tree

.github/workflows/base-deploy.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ jobs:
203203
TF_VAR_SPLUNK_HEC_TOKEN: ${{ secrets.SPLUNK_HEC_TOKEN }}
204204
TF_VAR_SPLUNK_HEC_ENDPOINT: ${{ secrets.SPLUNK_HEC_ENDPOINT }}
205205
TF_VAR_OPERATOR_EMAILS: ${{ vars.SECRET_ROTATION_OPERATOR_EMAILS }}
206-
TF_VAR_PROXYGEN_PRIVATE_KEY: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
206+
TF_VAR_PROXYGEN_PRIVATE_KEY_PTL: ${{ secrets.PROXYGEN_PRIVATE_KEY_PTL }}
207+
TF_VAR_PROXYGEN_PRIVATE_KEY_PROD: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
207208

208209
working-directory: ./infrastructure
209210
shell: bash

.github/workflows/cicd-2-publish.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ jobs:
103103
TF_VAR_SPLUNK_HEC_TOKEN: ${{ secrets.SPLUNK_HEC_TOKEN }}
104104
TF_VAR_SPLUNK_HEC_ENDPOINT: ${{ secrets.SPLUNK_HEC_ENDPOINT }}
105105
TF_VAR_OPERATOR_EMAILS: ${{ vars.SECRET_ROTATION_OPERATOR_EMAILS }}
106-
TF_VAR_PROXYGEN_PRIVATE_KEY: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
106+
TF_VAR_PROXYGEN_PRIVATE_KEY_PTL: ${{ secrets.PROXYGEN_PRIVATE_KEY_PTL }}
107+
TF_VAR_PROXYGEN_PRIVATE_KEY_PROD: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
107108

108109
run: |
109110
mkdir -p ./build

.github/workflows/cicd-3-test-deploy.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ jobs:
9090
TF_VAR_SPLUNK_HEC_TOKEN: ${{ secrets.SPLUNK_HEC_TOKEN }}
9191
TF_VAR_SPLUNK_HEC_ENDPOINT: ${{ secrets.SPLUNK_HEC_ENDPOINT }}
9292
TF_VAR_OPERATOR_EMAILS: ${{ vars.SECRET_ROTATION_OPERATOR_EMAILS }}
93-
TF_VAR_PROXYGEN_PRIVATE_KEY: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
93+
TF_VAR_PROXYGEN_PRIVATE_KEY_PTL: ${{ secrets.PROXYGEN_PRIVATE_KEY_PTL }}
94+
TF_VAR_PROXYGEN_PRIVATE_KEY_PROD: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
9495

9596
run: |
9697
mkdir -p ./build

.github/workflows/release-candidate.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ jobs:
237237
TF_VAR_SPLUNK_HEC_TOKEN: ${{ secrets.SPLUNK_HEC_TOKEN }}
238238
TF_VAR_SPLUNK_HEC_ENDPOINT: ${{ secrets.SPLUNK_HEC_ENDPOINT }}
239239
TF_VAR_OPERATOR_EMAILS: ${{ vars.SECRET_ROTATION_OPERATOR_EMAILS }}
240-
TF_VAR_PROXYGEN_PRIVATE_KEY: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
240+
TF_VAR_PROXYGEN_PRIVATE_KEY_PTL: ${{ secrets.PROXYGEN_PRIVATE_KEY_PTL }}
241+
TF_VAR_PROXYGEN_PRIVATE_KEY_PROD: ${{ secrets.PROXYGEN_PRIVATE_KEY_PROD }}
241242

242243
run: |
243244
mkdir -p ./build

infrastructure/stacks/iams-developer-roles/github_actions_policies.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ resource "aws_iam_policy" "api_infrastructure" {
400400
"ssm:ListTagsForResource",
401401
"ssm:PutParameter",
402402
"ssm:AddTagsToResource",
403+
"ssm:DeleteParameter",
403404

404405
# acm
405406
"acm:ListTagsForCertificate",
@@ -457,6 +458,8 @@ resource "aws_iam_policy" "api_infrastructure" {
457458
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:NHSDAudit_trail_log_group*",
458459
"arn:aws:ssm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:parameter/${var.environment}/*",
459460
"arn:aws:ssm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:parameter/splunk/*",
461+
"arn:aws:ssm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:parameter/ptl/*",
462+
"arn:aws:ssm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:parameter/prod/*",
460463
"arn:aws:acm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:certificate/*",
461464
"arn:aws:events:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:rule/cloudwatch-alarm-state-change-to-splunk*",
462465
"arn:aws:wafv2:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:regional/webacl/*",

infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ data "aws_iam_policy_document" "permissions_boundary" {
193193
"ssm:ListTagsForResource",
194194
"ssm:PutParameter",
195195
"ssm:AddTagsToResource",
196+
"ssm:DeleteParameter",
196197

197198
# WAFv2 - web application firewall management
198199
"wafv2:CreateWebACL",

infrastructure/stacks/networking/ssm.tf

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
resource "aws_ssm_parameter" "proxygen_private_key" {
2-
count = var.environment == "dev" ? 1 : 0
3-
name = "/${var.environment}/proxygen/private_key"
4-
type = "SecureString"
2+
for_each = var.environment == "dev" ? {
3+
ptl = { path = "/ptl/proxygen/private_key", value = var.PROXYGEN_PRIVATE_KEY_PTL }
4+
prod = { path = "/prod/proxygen/private_key", value = var.PROXYGEN_PRIVATE_KEY_PROD }
5+
} : {}
6+
7+
name = each.value.path
8+
type = "SecureString"
59
key_id = aws_kms_key.networking_ssm_key.id
6-
value = var.PROXYGEN_PRIVATE_KEY
10+
value = each.value.value
11+
712
tier = "Advanced"
813

914
tags = {

infrastructure/stacks/networking/variables.tf

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ variable "API_PRIVATE_KEY_CERT" {
1313
description = "The private key for the signed Client Certificate"
1414
sensitive = true
1515
}
16-
variable "PROXYGEN_PRIVATE_KEY" {
16+
variable "PROXYGEN_PRIVATE_KEY_PTL" {
1717
type = string
18-
description = "The private key for Proxygen authentication"
18+
description = "The private key for Proxygen `PTL` environment authentication"
19+
sensitive = true
20+
}
21+
variable "PROXYGEN_PRIVATE_KEY_PROD" {
22+
type = string
23+
description = "The private key for Proxygen `Prod` environment authentication"
1924
sensitive = true
2025
}

src/eligibility_signposting_api/services/processors/derived_values/add_days_handler.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class AddDaysHandler(DerivedValueHandler):
2727

2828
function_name: str = "ADD_DAYS"
2929

30-
# Mapping of derived attribute names to their source attributes
3130
DERIVED_ATTRIBUTE_SOURCES: ClassVar[dict[str, str]] = {
3231
"NEXT_DOSE_DUE": "LAST_SUCCESSFUL_DATE",
3332
}
@@ -62,7 +61,6 @@ def get_source_attribute(self, target_attribute: str, function_args: str | None
6261
The source attribute name (e.g., 'LAST_SUCCESSFUL_DATE')
6362
"""
6463
if function_args and "," in function_args:
65-
# Extract source from args if present (second argument)
6664
parts = [p.strip() for p in function_args.split(",")]
6765
if len(parts) > 1 and parts[1]:
6866
return parts[1].upper()
@@ -98,6 +96,9 @@ def calculate(self, context: DerivedValueContext) -> str:
9896
def _find_source_date(self, context: DerivedValueContext) -> str | None:
9997
"""Find the source date value from person data.
10098
99+
For PERSON/COHORT-level attributes, looks for ATTRIBUTE_TYPE == attribute_level.
100+
For TARGET-level attributes, looks for ATTRIBUTE_TYPE == context.attribute_name (e.g., "COVID").
101+
101102
Args:
102103
context: The derived value context
103104
@@ -108,8 +109,13 @@ def _find_source_date(self, context: DerivedValueContext) -> str | None:
108109
if not source_attr:
109110
return None
110111

112+
if context.attribute_level in ("PERSON", "COHORT"):
113+
attribute_type_to_match = context.attribute_level
114+
else:
115+
attribute_type_to_match = context.attribute_name
116+
111117
for attribute in context.person_data:
112-
if attribute.get("ATTRIBUTE_TYPE") == context.attribute_name:
118+
if attribute.get("ATTRIBUTE_TYPE") == attribute_type_to_match:
113119
return attribute.get(source_attr)
114120

115121
return None
@@ -128,7 +134,6 @@ def _get_days_to_add(self, context: DerivedValueContext) -> int:
128134
Returns:
129135
Number of days to add
130136
"""
131-
# Priority 1: Token argument (if non-empty)
132137
if context.function_args:
133138
args = context.function_args.split(",")[0].strip()
134139
if args:
@@ -138,11 +143,9 @@ def _get_days_to_add(self, context: DerivedValueContext) -> int:
138143
message = f"Invalid days argument '{args}' for ADD_DAYS function. Expected an integer."
139144
raise ValueError(message) from e
140145

141-
# Priority 2: Vaccine-specific configuration
142146
if context.attribute_name in self.vaccine_type_days:
143147
return self.vaccine_type_days[context.attribute_name]
144148

145-
# Priority 3: Default
146149
return self.default_days
147150

148151
def _add_days_to_date(self, date_str: str, days: int) -> datetime:

src/eligibility_signposting_api/services/processors/derived_values/base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ class DerivedValueContext:
99
1010
Attributes:
1111
person_data: List of person attribute dictionaries
12-
attribute_name: The condition/vaccine type (e.g., 'COVID', 'RSV')
12+
attribute_name: The condition/vaccine type (e.g., 'COVID', 'RSV') or person/cohort attribute
13+
(e.g., 'DATE_OF_BIRTH')
1314
source_attribute: The source attribute to derive from (e.g., 'LAST_SUCCESSFUL_DATE')
1415
function_args: Arguments passed to the function (e.g., number of days)
1516
date_format: Optional date format string for output formatting
17+
attribute_level: The level of the attribute ('TARGET', 'PERSON' or 'COHORT')
1618
"""
1719

1820
person_data: list[dict[str, Any]]
1921
attribute_name: str
2022
source_attribute: str | None
2123
function_args: str | None
2224
date_format: str | None
25+
attribute_level: str = "TARGET"
2326

2427

2528
class DerivedValueHandler(ABC):

0 commit comments

Comments
 (0)