Skip to content
Closed
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
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ GEM
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (~> 0.7)
ffi (1.17.1-aarch64-linux-gnu)
ffi (1.17.1-arm64-darwin)
ffi (1.17.1-x86_64-linux-gnu)
fhir_models (5.0.0)
Expand Down Expand Up @@ -394,6 +395,8 @@ GEM
net-protocol
nio4r (2.7.4)
nkf (0.2.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
Expand Down Expand Up @@ -743,6 +746,7 @@ GEM
zeitwerk (2.7.3)

PLATFORMS
aarch64-linux
arm64-darwin-22
arm64-darwin-23
arm64-darwin-24
Expand Down
3 changes: 0 additions & 3 deletions app/controllers/api/reporting/one_time_tokens_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,4 @@ def jwt(token)
)
end

def ensure_reporting_api_feature_enabled
render status: :forbidden and return unless Flipper.enabled?(:reporting_api)
end
end
5 changes: 5 additions & 0 deletions config/feature_flags.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@

reporting_api: Enables the Commissioner reporting component to authenticate to Mavis via OAUTH 2.0
Authorization Code Flow (https://datatracker.ietf.org/doc/html/rfc6749#section-4.1), and retrieve
statistics from /api/reporting/

basic_auth: Require users to sign in with basic authentication before they
can use the service.

Expand Down
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
get "totals", controller: :totals, action: :index
end
end
namespace :reporting do
post "authorize", to: "one_time_tokens#authorize"
get "totals", controller: :totals, action: :index
end
end

resources :class_imports, path: "class-imports", except: %i[index destroy]
Expand Down
2 changes: 1 addition & 1 deletion docs/ops-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ session.patient_sessions.all?(&:safe_to_destroy?)
session.patients.update_all(
cohort_id: nil,
home_educated: false,
school_id: nil
school_id: nil,
)

# removes all patients from the session
Expand Down
2 changes: 1 addition & 1 deletion docs/reporting-component-authentication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ifdef::env-github[]
// When PRing changes to the diagrams you can change this attributes
// temporarily to the name of the branch you're working on. But don't forget
// to change it back to main before merging!!
:github-branch: main
:github-branch: spike/MAV-1406-auth-sharing-with-reporting

:github-repo: nhsuk/manage-vaccinations-in-schools

Expand Down
13 changes: 13 additions & 0 deletions spec/controllers/concerns/authentication_concern_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
Class
.new do # rubocop:disable Style/BlockDelimiters
include AuthenticationConcern
attr_accessor :request, :session

def initialize(request: nil, session: {})
@request = request
@session = session
end

def params
{}
end

def render(content = {}, args = {})
end

attr_accessor :request, :session

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,13 @@ def and_an_existing_patient_record_exists
@existing_patient_duplicate_review_on_demographics =
create(
:patient,
given_name: "Maia",
given_name# It looks like the code snippet is incomplete and contains a syntax error. The code
# seems to be attempting to assign a value to a variable named
# `ent_duplicate_review_on_demographics`, but it is missing the assignment operator
# and the value to be assigned. Additionally, the word "crea" does not seem to be a
# valid Ruby keyword or variable name. Please provide more context or correct the
# code snippet for further assistance.
: "Maia",
family_name: "Smith",
nhs_number: nil,
date_of_birth: Date.new(2010, 8, 15), # Different from CSV
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/cohort_import/pds_extravaganza.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ CHILD_SCHOOL_URN,PARENT_1_NAME,PARENT_1_RELATIONSHIP,PARENT_1_EMAIL,PARENT_1_PHO
123456,Jane Doe,,,01234567896,,,,,Oliver,Green,,2010-08-15,8,789 Silent Street,,London,SW1W 8JL,9435753868
123456,,,,,,,,,Lara,Williams,,2010-05-15,8,,,,B1 1AA,
123456,,,,,,,,,Lucy,McCarthy,,2010-08-16,8,789 Silent Street,,London,SW7 5LE,9435815065
123456,,,,,,,,,Maia,Smith,,2010-08-16,8,790 Silent Street,,London,W2 3PE,9435789102
123456,,,,,,,,,Maia,Smith,,2010-08-16,8,790 Silent Street,,London,W2 3PE,9435789102
55 changes: 42 additions & 13 deletions terraform/account/deployment_permissions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ resource "aws_iam_role" "mavis_deploy" {
name = "GithubDeployMavisAndInfrastructure"
description = "Role allowing terraform deployment from github workflows"
assume_role_policy = templatefile("resources/iam_role_github_trust_policy_${var.environment}.json.tftpl", {
account_id = var.account_id
account_id = var.account_id,
repository = "nhsuk/manage-vaccinations-in-schools"
})
}

Expand All @@ -27,7 +28,8 @@ resource "aws_iam_role" "data_replication_deploy" {
name = "GithubDeployDataReplicationInfrastructure"
description = "Role to be assumed by github workflows dealing with the creation and destruction of the data-replication infrastructure."
assume_role_policy = templatefile("resources/iam_role_github_trust_policy_${var.environment}.json.tftpl", {
account_id = var.account_id
account_id = var.account_id,
repository = "nhsuk/manage-vaccinations-in-schools"
})
}

Expand All @@ -46,28 +48,55 @@ resource "aws_iam_role_policy_attachment" "data_replication" {
policy_arn = each.value
}

################ Deploy ECS Service ################

resource "aws_iam_role" "deploy_ecs_service" {
name = "GithubDeployECSService"
description = "Role allowing terraform deployment of ECS services from github workflows"
assume_role_policy = templatefile("resources/iam_role_github_trust_policy_${var.environment}.json.tftpl", {
account_id = var.account_id,
repository = "NHSDigital/manage-vaccinations-in-schools-reporting"
})
}

resource "aws_iam_policy" "deploy_ecs_service" {
name = "DeployECSServiceResources"
description = "Permissions for GithubDeployECSService role"
policy = file("resources/iam_policy_DeployECSServiceResources.json")
lifecycle {
ignore_changes = [description]
}
}

resource "aws_iam_role_policy_attachment" "deploy_ecs_service" {
for_each = local.ecs_deploy_policies
role = aws_iam_role.deploy_ecs_service.name
policy_arn = each.value
}

################# Deploy Monitoring ################

resource "aws_iam_role" "monitoring_deploy" {
name = "GithubDeployMonitoring"
description = "Role allowing terraform deployment of monitoring resources from github workflows"
resource "aws_iam_role" "deploy_ecs_service" {
name = "GithubDeployECSService"
description = "Role allowing terraform deployment of ECS services from github workflows"
assume_role_policy = templatefile("resources/iam_role_github_trust_policy_${var.environment}.json.tftpl", {
account_id = var.account_id
account_id = var.account_id,
repository = "nhsuk/manage-vaccinations-in-schools"
})
}

resource "aws_iam_policy" "monitoring_deploy" {
name = "DeployMonitoringResources"
description = "Permissions for GithubDeployMonitoring role"
policy = file("resources/iam_policy_DeployMonitoringResources.json")
resource "aws_iam_policy" "deploy_ecs_service" {
name = "DeployECSServiceResources"
description = "Permissions for GithubDeployECSService role"
policy = file("resources/iam_policy_DeployECSServiceResources.json")
lifecycle {
ignore_changes = [description]
}
}

resource "aws_iam_role_policy_attachment" "monitoring_deploy" {
for_each = local.monitoring_policies
role = aws_iam_role.monitoring_deploy.name
resource "aws_iam_role_policy_attachment" "deploy_ecs_service" {
for_each = local.ecs_deploy_policies
role = aws_iam_role.deploy_ecs_service.name
policy_arn = each.value
}

Expand Down
5 changes: 5 additions & 0 deletions terraform/account/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ resource "aws_ecr_lifecycle_policy" "mavis" {
})
}

resource "aws_ecr_repository" "mavis_reporting" {
name = "mavis/reporting"
image_tag_mutability = "MUTABLE"
}


#### Access Analyzer

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices",
"ecs:ListServices",
"ecs:RegisterTaskDefinition",
"ecs:DeregisterTaskDefinition",
"ecs:DescribeTaskDefinition",
"ecs:ListTaskDefinitions",
"ecs:DescribeClusters",
"ecs:DescribeTasks",
"ecs:DescribeTaskSets",
"ecs:StartTask",
"ecs:ListServiceDeployments",
"ecs:DescribeServiceDeployments",
"ecs:UntagResource",
"ecs:TagResource",
"ecs:ListClusters",
"ecs:ListContainerInstances",
"ecs:ListTaskDefinitionFamilies",
"ecs:ListTasks",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"codedeploy:BatchGetApplicationRevisions",
"codedeploy:BatchGetApplications",
"codedeploy:BatchGetDeploymentGroups",
"codedeploy:BatchGetDeployments",
"codedeploy:ContinueDeployment",
"codedeploy:CreateApplication",
"codedeploy:CreateDeployment",
"codedeploy:CreateDeploymentGroup",
"codedeploy:GetApplication",
"codedeploy:GetApplicationRevision",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:GetDeploymentGroup",
"codedeploy:GetDeploymentTarget",
"codedeploy:ListApplicationRevisions",
"codedeploy:ListApplications",
"codedeploy:ListDeploymentConfigs",
"codedeploy:ListDeploymentGroups",
"codedeploy:ListDeployments",
"codedeploy:ListDeploymentTargets",
"codedeploy:RegisterApplicationRevision",
"codedeploy:StopDeployment",
"ssm:DescribeParameters",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"iam:PassRole"
],
"Resource": ["*"]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@
"elasticache:ModifyCacheParameterGroup",
"elasticache:ModifyCacheSubnetGroup",
"elasticache:IncreaseReplicaCount"
"lambda:InvokeFunction",
"lambda:DeleteFunction",
"lambda:CreateFunction",
"lambda:CreateAlias",
"lambda:DeleteAlias",
"lambda:UpdateAlias"
],
"Resource": ["*"]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:nhsuk/manage-vaccinations-in-schools:*"
"token.actions.githubusercontent.com:sub": "repo:${repository}:*"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": [
"repo:nhsuk/manage-vaccinations-in-schools:ref:refs/heads/main",
"repo:nhsuk/manage-vaccinations-in-schools:environment:production"
"repo:${repository}:ref:refs/heads/main",
"repo:${repository}:environment:production"
],
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
Expand Down
5 changes: 5 additions & 0 deletions terraform/account/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ locals {
mavis_deploy = aws_iam_policy.mavis_deploy.arn
})

ecs_deploy_policies = {
ecr_read = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
deploy_ecs_service = aws_iam_policy.deploy_ecs_service.arn
}

monitoring_policies = merge(local.base_policies, {
monitoring_deploy = aws_iam_policy.monitoring_deploy.arn
})
Expand Down
49 changes: 49 additions & 0 deletions terraform/app/codedeploy.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,55 @@ resource "aws_codedeploy_deployment_group" "blue_green_deployment_group" {
}
}

resource "aws_codedeploy_deployment_group" "reporting" {
app_name = aws_codedeploy_app.mavis.name
deployment_config_name = "CodeDeployDefault.ECSAllAtOnce"
deployment_group_name = "reporting-${var.environment}"
service_role_arn = aws_iam_role.code_deploy.arn

auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE"]
}

blue_green_deployment_config {
deployment_ready_option {
action_on_timeout = "CONTINUE_DEPLOYMENT"
}

terminate_blue_instances_on_deployment_success {
action = "TERMINATE"
termination_wait_time_in_minutes = 1
}
}

deployment_style {
deployment_option = "WITH_TRAFFIC_CONTROL"
deployment_type = "BLUE_GREEN"
}

ecs_service {
cluster_name = aws_ecs_cluster.cluster.name
service_name = module.reporting_service.service.name
}

load_balancer_info {
target_group_pair_info {
prod_traffic_route {
listener_arns = [aws_lb_listener.app_listener_https.arn]
}

target_group {
name = aws_lb_target_group.reporting_blue.name
}

target_group {
name = aws_lb_target_group.reporting_green.name
}
}
}
}

resource "aws_s3_bucket" "code_deploy_bucket" {
bucket = var.appspec_bucket
force_destroy = true
Expand Down
Loading
Loading