-
Notifications
You must be signed in to change notification settings - Fork 13
Add Django admin form to allow Helpdesk to update UEI/EIN #5232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
LynnMHouston
wants to merge
2
commits into
main
Choose a base branch
from
lh/uei-ein-admin-override
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Contributor
|
Terraform plan for meta No changes. Your infrastructure matches the configuration.📝 Plan generated in Pull Request Checks #169 |
Contributor
|
Terraform plan for dev Plan: 6 to add, 10 to change, 6 to destroy.Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
!~ update in-place
-/+ destroy and then create replacement
<= read (data resources)
Terraform will perform the following actions:
# module.dev.cloudfoundry_network_policy.app-network-policy will be updated in-place
!~ resource "cloudfoundry_network_policy" "app-network-policy" {
!~ policies = [
!~ {
!~ destination_app = "830bfc16-6865-4644-a3f3-5a1a69d6ec5f" -> (known after apply)
# (3 unchanged attributes hidden)
},
!~ {
!~ destination_app = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> (known after apply)
# (3 unchanged attributes hidden)
},
!~ {
!~ destination_app = "830bfc16-6865-4644-a3f3-5a1a69d6ec5f" -> (known after apply)
# (3 unchanged attributes hidden)
},
]
}
# module.dev.cloudfoundry_network_policy.clamav-network-policy will be updated in-place
!~ resource "cloudfoundry_network_policy" "clamav-network-policy" {
!~ policies = [
!~ {
!~ destination_app = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> (known after apply)
!~ source_app = "830bfc16-6865-4644-a3f3-5a1a69d6ec5f" -> (known after apply)
# (2 unchanged attributes hidden)
},
!~ {
!~ destination_app = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> (known after apply)
!~ source_app = "d9fa2027-96c9-4f98-bdb8-13809c6f569a" -> (known after apply)
# (2 unchanged attributes hidden)
},
]
}
# module.dev.cloudfoundry_network_policy.logshipper-network-policy will be updated in-place
!~ resource "cloudfoundry_network_policy" "logshipper-network-policy" {
!~ policies = [
!~ {
!~ destination_app = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> (known after apply)
!~ source_app = "92483ac7-d368-43b0-b429-0170e3e2b2c2" -> (known after apply)
# (2 unchanged attributes hidden)
},
]
}
# module.dev.cloudfoundry_network_policy.scanner-network-policy will be updated in-place
!~ resource "cloudfoundry_network_policy" "scanner-network-policy" {
!~ policies = [
!~ {
!~ destination_app = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> (known after apply)
!~ source_app = "a0669f56-c5a5-4c35-85bf-5b6201478ad5" -> (known after apply)
# (2 unchanged attributes hidden)
},
!~ {
!~ destination_app = "d9fa2027-96c9-4f98-bdb8-13809c6f569a" -> (known after apply)
!~ source_app = "a0669f56-c5a5-4c35-85bf-5b6201478ad5" -> (known after apply)
# (2 unchanged attributes hidden)
},
]
}
# module.dev.module.cg-logshipper.cloudfoundry_app.logshipper_app will be updated in-place
!~ resource "cloudfoundry_app" "logshipper_app" {
!~ created_at = "2025-04-21T18:47:16Z" -> (known after apply)
!~ enable_ssh = false -> (known after apply)
!~ id = "************************************" -> (known after apply)
!~ log_rate_limit_per_second = "-1" -> (known after apply)
name = "logshipper"
!~ readiness_health_check_type = "process" -> (known after apply)
!~ routes = [
- {
- protocol = "http1" -> null
- route = "fac-dev-logshipper.app.cloud.gov" -> null
},
] -> (known after apply)
!~ source_code_hash = "adb965edbd40cfe6e31aa5a6d9dc2a1ab27fc8954f787fefebb9fac9e2f1c9e2" -> "f95cf383ea3d0b14111c608a076adfd3a338a57cdbc7b830b16d2f6155529715"
!~ stack = "cflinuxfs4" -> (known after apply)
!~ updated_at = "2025-08-22T19:05:14Z" -> (known after apply)
# (12 unchanged attributes hidden)
}
# module.dev.module.cg-logshipper.cloudfoundry_route.logshipper_route will be updated in-place
!~ resource "cloudfoundry_route" "logshipper_route" {
!~ destinations = [
- {
- app_id = "92483ac7-d368-43b0-b429-0170e3e2b2c2" -> null
- app_process_type = "web" -> null
- id = "cb430c0b-be04-428f-b94f-0af6d42d100b" -> null
- port = 8080 -> null
- protocol = "http1" -> null
},
+ {
+ app_id = (known after apply)
+ app_process_type = (known after apply)
+ id = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
},
]
id = "3aec8f3f-c16b-4528-bc10-021921a7c5c6"
!~ updated_at = "2025-04-21T18:49:17Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.dev.module.clamav.cloudfoundry_app.clamav_api must be replaced
-/+ resource "cloudfoundry_app" "clamav_api" {
+ buildpacks = (known after apply)
!~ created_at = "2025-08-12T17:37:02Z" -> (known after apply)
!~ docker_image = "ghcr.io/gsa-tts/fac/clamav@sha256:f0b490065d736a7c4151744e04683760418fe7a43ba9e14102b162305d94966a" -> "ghcr.io/gsa-tts/fac/clamav@sha256:3c7acdf614fba2604a5aaf4a015c803a02a6bb79cd68f1636577557a0a9384bf"
!~ enable_ssh = false -> (known after apply)
!~ health_check_type = "port" -> (known after apply)
!~ id = "************************************" -> (known after apply)
!~ log_rate_limit_per_second = "-1" -> (known after apply)
name = "fac-av-dev"
!~ readiness_health_check_type = "process" -> (known after apply)
!~ routes = [
- {
- protocol = "http1" -> null
- route = "fac-av-dev.apps.internal" -> null
},
] -> (known after apply)
+ service_bindings = (known after apply) # forces replacement
!~ stack = null -> (known after apply)
!~ updated_at = "2025-08-12T17:37:09Z" -> (known after apply)
# (8 unchanged attributes hidden)
}
# module.dev.module.cors.null_resource.cors_header must be replaced
-/+ resource "null_resource" "cors_header" {
!~ id = "*******************" -> (known after apply)
!~ triggers = { # forces replacement
!~ "always_run" = "2025-08-22T18:58:30Z" -> (known after apply)
}
}
# module.dev.module.fac-file-scanner.data.cloudfoundry_domain.internal will be read during apply
# (depends on a resource or a module with changes pending)
<= data "cloudfoundry_domain" "internal" {
+ annotations = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ internal = (known after apply)
+ labels = (known after apply)
+ name = "apps.internal"
+ org = (known after apply)
+ router_group = (known after apply)
+ shared_orgs = (known after apply)
+ supported_protocols = (known after apply)
+ updated_at = (known after apply)
}
# module.dev.module.fac-file-scanner.data.external.scannerzip will be read during apply
# (depends on a resource or a module with changes pending)
<= data "external" "scannerzip" {
+ id = (known after apply)
+ program = [
+ "/bin/sh",
+ "prepare-scanner.sh",
]
+ query = {
+ "gitref" = "refs/heads/main"
}
+ result = (known after apply)
+ working_dir = "../shared/modules/scanner"
}
# module.dev.module.fac-file-scanner.cloudfoundry_app.scanner_app will be updated in-place
!~ resource "cloudfoundry_app" "scanner_app" {
!~ created_at = "2025-04-21T18:53:54Z" -> (known after apply)
!~ enable_ssh = false -> (known after apply)
!~ id = "************************************" -> (known after apply)
!~ log_rate_limit_per_second = "-1" -> (known after apply)
name = "fac-file-scanner"
!~ path = "../shared/modules/scanner/scanner.zip" -> (known after apply)
!~ readiness_health_check_type = "process" -> (known after apply)
!~ routes = [
- {
- protocol = "http1" -> null
- route = "fac-file-scanner-dev.apps.internal" -> null
},
] -> (known after apply)
!~ source_code_hash = "ded718cecee8f31a86dc4d7ec55a1f7d04e168bad29fd3aaa337fda8ce3c575d" -> (known after apply)
!~ stack = "cflinuxfs4" -> (known after apply)
!~ updated_at = "2025-08-12T17:39:09Z" -> (known after apply)
# (11 unchanged attributes hidden)
}
# module.dev.module.fac-file-scanner.cloudfoundry_route.scanner_route must be replaced
-/+ resource "cloudfoundry_route" "scanner_route" {
!~ created_at = "2025-08-22T18:59:03Z" -> (known after apply)
!~ destinations = [
- {
- app_id = "a0669f56-c5a5-4c35-85bf-5b6201478ad5" -> null
- app_process_type = "web" -> null
- id = "8113b713-dba0-4ad6-aa15-1d3cfb354d37" -> null
- port = 8080 -> null
- protocol = "http1" -> null
},
+ {
+ app_id = (known after apply)
+ app_process_type = (known after apply)
+ id = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
},
]
!~ domain = "26df58ef-0c0d-4997-b68b-8defb7b3998b" -> (known after apply) # forces replacement
!~ id = "************************************" -> (known after apply)
!~ protocol = "http" -> (known after apply)
!~ updated_at = "2025-08-22T18:59:03Z" -> (known after apply)
!~ url = "fac-file-scanner-dev.apps.internal" -> (known after apply)
# (2 unchanged attributes hidden)
}
# module.dev.module.file_scanner_clamav.cloudfoundry_app.clamav_api must be replaced
-/+ resource "cloudfoundry_app" "clamav_api" {
+ buildpacks = (known after apply)
!~ created_at = "2025-08-12T17:39:11Z" -> (known after apply)
!~ docker_image = "ghcr.io/gsa-tts/fac/clamav@sha256:f0b490065d736a7c4151744e04683760418fe7a43ba9e14102b162305d94966a" -> "ghcr.io/gsa-tts/fac/clamav@sha256:3c7acdf614fba2604a5aaf4a015c803a02a6bb79cd68f1636577557a0a9384bf"
!~ enable_ssh = false -> (known after apply)
!~ health_check_type = "port" -> (known after apply)
!~ id = "************************************" -> (known after apply)
!~ log_rate_limit_per_second = "-1" -> (known after apply)
name = "fac-av-dev-fs"
!~ readiness_health_check_type = "process" -> (known after apply)
!~ routes = [
- {
- protocol = "http1" -> null
- route = "fac-av-dev-fs.apps.internal" -> null
},
] -> (known after apply)
+ service_bindings = (known after apply) # forces replacement
!~ stack = null -> (known after apply)
!~ updated_at = "2025-08-12T17:39:17Z" -> (known after apply)
# (8 unchanged attributes hidden)
}
# module.dev.module.https-proxy.cloudfoundry_app.egress_app must be replaced
-/+ resource "cloudfoundry_app" "egress_app" {
!~ created_at = "2025-08-22T18:58:42Z" -> (known after apply)
!~ disk_quota = "2048M" -> (known after apply)
!~ enable_ssh = false -> (known after apply)
!~ health_check_type = "port" -> (known after apply)
!~ id = "************************************" -> (known after apply)
!~ log_rate_limit_per_second = "-1" -> (known after apply)
name = "https-proxy"
!~ readiness_health_check_type = "process" -> (known after apply)
!~ routes = [
- {
- protocol = "http1" -> null
- route = "gsa-tts-oros-fac-dev-egress-https-proxy.apps.internal" -> null
},
] -> (known after apply)
+ service_bindings = (known after apply) # forces replacement
!~ source_code_hash = "9f9625544eba6b73c600173bd2a2a380d2f756ad82014fe70f55454c2b14a1c0" -> "2b6290297493a04793de94e6e62ba1483b63db68ccf1bc704507d06c6403c64e"
!~ stack = "cflinuxfs4" -> (known after apply)
!~ updated_at = "2025-08-22T19:05:06Z" -> (known after apply)
# (9 unchanged attributes hidden)
}
# module.dev.module.https-proxy.cloudfoundry_route.egress_route will be updated in-place
!~ resource "cloudfoundry_route" "egress_route" {
!~ destinations = [
- {
- app_id = "8a7aac9b-d5ba-4321-a947-adfa18a42bfa" -> null
- app_process_type = "web" -> null
- id = "8cbf00c3-bd49-4418-add5-e87b40a18577" -> null
- port = 8080 -> null
- protocol = "http1" -> null
},
+ {
+ app_id = (known after apply)
+ app_process_type = (known after apply)
+ id = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
},
]
id = "13dc80b5-4d3b-4181-b7c1-b6dc8d5a0e65"
!~ updated_at = "2025-08-22T18:59:02Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.dev.module.clamav.module.route.cloudfoundry_route.app_route will be updated in-place
!~ resource "cloudfoundry_route" "app_route" {
!~ destinations = [
- {
- app_id = "830bfc16-6865-4644-a3f3-5a1a69d6ec5f" -> null
- app_process_type = "web" -> null
- id = "e72b846c-1652-4ba8-ab3e-03ed29621a63" -> null
- port = 8080 -> null
- protocol = "http1" -> null
},
+ {
+ app_id = (known after apply)
+ app_process_type = (known after apply)
+ id = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
},
]
id = "877bbc1f-e036-4a96-b7a3-70cff8c35c3c"
!~ updated_at = "2025-08-12T17:37:10Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.dev.module.fac-file-scanner.module.quarantine.data.cloudfoundry_service_plans.s3 will be read during apply
# (depends on a resource or a module with changes pending)
<= data "cloudfoundry_service_plans" "s3" {
+ name = "basic"
+ service_offering_name = "s3"
+ service_plans = (known after apply)
}
# module.dev.module.fac-file-scanner.module.quarantine.cloudfoundry_service_instance.bucket will be updated in-place
!~ resource "cloudfoundry_service_instance" "bucket" {
+ dashboard_url = (known after apply)
id = "c435cb9c-32a7-4a31-828b-48c8c6f3bf37"
!~ last_operation = {
!~ created_at = "2025-03-14T14:22:42Z" -> (known after apply)
+ description = (known after apply)
!~ state = "succeeded" -> (known after apply)
!~ type = "update" -> (known after apply)
!~ updated_at = "2025-03-14T14:22:42Z" -> (known after apply)
} -> (known after apply)
!~ maintenance_info = {
+ description = (known after apply)
+ version = (known after apply)
} -> (known after apply)
name = "fac-file-scanner-quarantine"
!~ service_plan = "021bb2a3-7e11-4fc2-b06b-d9f5938cd806" -> (known after apply)
tags = [
"s3",
"terraform-cloudgov-managed",
]
!~ updated_at = "2025-03-14T14:22:42Z" -> (known after apply)
!~ upgrade_available = false -> (known after apply)
# (3 unchanged attributes hidden)
}
# module.dev.module.file_scanner_clamav.module.route.data.cloudfoundry_domain.domain will be read during apply
# (depends on a resource or a module with changes pending)
<= data "cloudfoundry_domain" "domain" {
+ annotations = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ internal = (known after apply)
+ labels = (known after apply)
+ name = "apps.internal"
+ org = (known after apply)
+ router_group = (known after apply)
+ shared_orgs = (known after apply)
+ supported_protocols = (known after apply)
+ updated_at = (known after apply)
}
# module.dev.module.file_scanner_clamav.module.route.data.cloudfoundry_org.org will be read during apply
# (depends on a resource or a module with changes pending)
<= data "cloudfoundry_org" "org" {
+ annotations = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ labels = (known after apply)
+ name = "gsa-tts-oros-fac"
+ quota = (known after apply)
+ suspended = (known after apply)
+ updated_at = (known after apply)
}
# module.dev.module.file_scanner_clamav.module.route.data.cloudfoundry_space.space will be read during apply
# (config refers to values not yet known)
<= data "cloudfoundry_space" "space" {
+ allow_ssh = (known after apply)
+ annotations = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ isolation_segment = (known after apply)
+ labels = (known after apply)
+ name = "dev"
+ org = (known after apply)
+ quota = (known after apply)
+ updated_at = (known after apply)
}
# module.dev.module.file_scanner_clamav.module.route.cloudfoundry_route.app_route must be replaced
-/+ resource "cloudfoundry_route" "app_route" {
!~ created_at = "2025-08-22T18:59:03Z" -> (known after apply)
!~ destinations = [
- {
- app_id = "d9fa2027-96c9-4f98-bdb8-13809c6f569a" -> null
- app_process_type = "web" -> null
- id = "ca09f24f-42c2-4f01-b2ce-d9dcec58286d" -> null
- port = 8080 -> null
- protocol = "http1" -> null
},
+ {
+ app_id = (known after apply)
+ app_process_type = (known after apply)
+ id = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
},
]
!~ domain = "26df58ef-0c0d-4997-b68b-8defb7b3998b" -> (known after apply) # forces replacement
!~ id = "************************************" -> (known after apply)
!~ protocol = "http" -> (known after apply)
!~ space = "06525ba3-19c2-451b-96e9-ea4a9134e8b9" -> (known after apply) # forces replacement
!~ updated_at = "2025-08-22T18:59:03Z" -> (known after apply)
!~ url = "fac-av-dev-fs.apps.internal" -> (known after apply)
# (1 unchanged attribute hidden)
}
Plan: 6 to add, 10 to change, 6 to destroy.📝 Plan generated in Pull Request Checks #169 |
Contributor
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This adds a Django admin form so Helpdesk (or superusers) can update the UEI/EIN on a
SingleAuditChecklistwhen needed.SingleAuditChecklistadmin view and doesn’t affect any other models.save_model()so the changes get tagged as anadmin-overrideand logged in bothSubmissionEventandHistory.This change is scoped to this one override feature only.
You should see a
SubmissionEventandHistoryrecord if the change is saved properly.Why We Need It
We’re currently sitting on a number of potential UEI/EIN corrections that go beyond the existing manual process. This allows Helpdesk to resolve those directly, without needing to escalate to Engineering. It’s only exposed to Helpdesk and superusers, and it logs an audit trail for transparency.
PR Checklist: Submitter
maininto your branch shortly before creating the PR. (You should also be mergingmaininto your branch regularly during development.)git status | grep migrations. If there are any results, you probably need to add them to the branch for the PR. Your PR should have only one new migration file for each of the component apps, except in rare circumstances; you may need to delete some and re-runpython manage.py makemigrationsto reduce the number to one. (Also, unless in exceptional circumstances, your PR should not delete any migration files.)PR Checklist: Reviewer
make docker-clean; make docker-first-run && docker compose up; then rundocker compose exec web /bin/bash -c "python manage.py test"The larger the PR, the stricter we should be about these points.
Pre Merge Checklist: Merger
-/+ resource "null_resource" "cors_header"should be destroying and recreating its self and~ resource "cloudfoundry_app" "clamav_api"might be updating itssha256for thefac-file-scannerandfac-av-${ENV}by default.main.