rails_template_18f 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +57 -55
- data/README.md +102 -29
- data/exe/rails_template_18f +0 -21
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +2 -2
- data/lib/generators/rails_template18f/auditree/auditree_generator.rb +34 -3
- data/lib/generators/rails_template18f/auditree/templates/bin/auditree.tt +85 -11
- data/lib/generators/rails_template18f/auditree/templates/github/actions/auditree-cmd/action.yml.tt +17 -6
- data/lib/generators/rails_template18f/auditree/templates/github/workflows/auditree-validation.yml.tt +2 -6
- data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +13 -7
- data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +1 -1
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +0 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/dependabot.yml.tt +25 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/assemble-ssp.yml.tt +12 -3
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/brakeman-analysis.yml +1 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +8 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +8 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/rspec.yml.tt +9 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/{validate-ssp.yml.tt → validate-ssp.yml} +1 -1
- data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +12 -20
- data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js +11 -0
- data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +4 -0
- data/lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb +5 -0
- data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +8 -7
- data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +1 -1
- data/lib/generators/rails_template18f/oscal/oscal_generator.rb +14 -1
- data/lib/generators/rails_template18f/oscal/templates/bin/trestle.tt +4 -1
- data/lib/generators/rails_template18f/oscal/templates/github/actions/trestle-cmd/action.yml.tt +16 -0
- data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +136 -0
- data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +1 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +2 -2
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +1 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +2 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +1 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +25 -5
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +22 -4
- data/lib/rails_template18f/generators/base.rb +7 -0
- data/lib/rails_template18f/generators/cloud_gov_options.rb +7 -27
- data/lib/rails_template18f/generators/cloud_gov_parsing.rb +41 -0
- data/lib/rails_template18f/generators.rb +1 -0
- data/lib/rails_template18f/version.rb +1 -1
- data/rails-template-18f.gemspec +3 -3
- data/railsrc +2 -0
- data/railsrc-hotwire +2 -0
- data/template.rb +19 -12
- data/templates/bin/ops/create_service_account.sh.tt +14 -2
- data/templates/bin/ops/destroy_service_account.sh.tt +0 -3
- data/templates/lib/tasks/scanning.rake +1 -1
- data/templates/manifest.yml.tt +1 -1
- metadata +19 -14
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/trestle-cmd/action.yml +0 -20
- data/lib/rails_template18f/app_updater.rb +0 -19
- /data/lib/generators/rails_template18f/terraform/templates/terraform/production/{providers.tf.tt → providers.tf} +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/terraform/staging/{providers.tf.tt → providers.tf} +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "colorize"
|
|
5
|
+
|
|
6
|
+
module RailsTemplate18f
|
|
7
|
+
module Generators
|
|
8
|
+
class PublicEgressGenerator < ::Rails::Generators::Base
|
|
9
|
+
include Base
|
|
10
|
+
include CloudGovParsing
|
|
11
|
+
|
|
12
|
+
desc <<~DESC
|
|
13
|
+
Description:
|
|
14
|
+
Install files for running cg-egress-proxy in <env>-egress cloud.gov spaces
|
|
15
|
+
Prerequisite: the terraform generator has been run already
|
|
16
|
+
DESC
|
|
17
|
+
|
|
18
|
+
def check_terraform_exists
|
|
19
|
+
unless terraform_dir_exists?
|
|
20
|
+
fail "Run `rails g rails_template18f:terraform` before running this generator"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def use_terraform_module
|
|
25
|
+
append_to_file file_path("terraform/staging/main.tf"), terraform_module
|
|
26
|
+
append_to_file file_path("terraform/production/main.tf"), terraform_module
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def add_to_deploy_steps
|
|
30
|
+
if file_exists?(".github/workflows/deploy-staging.yml")
|
|
31
|
+
insert_into_file ".github/workflows/deploy-staging.yml", <<EOD, before: " - name: Deploy app"
|
|
32
|
+
- name: Set public egress
|
|
33
|
+
uses: cloud-gov/cg-cli-tools@main
|
|
34
|
+
with:
|
|
35
|
+
cf_username: ${{ secrets.CF_USERNAME }}
|
|
36
|
+
cf_password: ${{ secrets.CF_PASSWORD }}
|
|
37
|
+
cf_org: #{cloud_gov_organization}
|
|
38
|
+
cf_space: #{cloud_gov_staging_space}-egress
|
|
39
|
+
cf_command: bind-security-group public_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
|
|
40
|
+
EOD
|
|
41
|
+
end
|
|
42
|
+
if file_exists?(".github/workflows/deploy-production.yml")
|
|
43
|
+
insert_into_file ".github/workflows/deploy-production.yml", <<EOD, before: " - name: Deploy app"
|
|
44
|
+
- name: Set public egress
|
|
45
|
+
uses: cloud-gov/cg-cli-tools@main
|
|
46
|
+
with:
|
|
47
|
+
cf_username: ${{ secrets.CF_USERNAME }}
|
|
48
|
+
cf_password: ${{ secrets.CF_PASSWORD }}
|
|
49
|
+
cf_org: #{cloud_gov_organization}
|
|
50
|
+
cf_space: #{cloud_gov_production_space}-egress
|
|
51
|
+
cf_command: bind-security-group public_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
|
|
52
|
+
EOD
|
|
53
|
+
end
|
|
54
|
+
if file_exists?(".circleci/config.yml")
|
|
55
|
+
insert_into_file ".circleci/config.yml", <<EOD, before: " name: Push application with deployment vars"
|
|
56
|
+
name: Set public egress
|
|
57
|
+
command: |
|
|
58
|
+
cf bind-security-group public_networks_egress << parameters.cloudgov_org >> \
|
|
59
|
+
--space << parameters.cloudgov_space >>-egress
|
|
60
|
+
- run:
|
|
61
|
+
EOD
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def update_readme
|
|
66
|
+
insert_into_file "README.md", readme_content, before: "## Documentation"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def update_boundary_diagram
|
|
70
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
|
71
|
+
insert_into_file boundary_filename, <<EOB, after: "System_Boundary(inventory, \"Application\") {\n"
|
|
72
|
+
Boundary(restricted_space, "Restricted egress space") {
|
|
73
|
+
}
|
|
74
|
+
Boundary(egress_space, "Public egress space") {
|
|
75
|
+
Container(proxy, "<&layers> Egress Proxy", "Caddy, cg-egress-proxy", "Proxy with allow-list of external connections")
|
|
76
|
+
}
|
|
77
|
+
EOB
|
|
78
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
|
79
|
+
Rel(app, proxy, "Proxy outbound connections", "https (443)")
|
|
80
|
+
EOB
|
|
81
|
+
puts "\n ================ TODO ================ \n".yellow
|
|
82
|
+
puts "Update your application boundary to:"
|
|
83
|
+
puts "1. Place application and services within the Restricted egress space"
|
|
84
|
+
puts "2. Connect outbound connections through the egress proxy"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def update_oscal_doc
|
|
88
|
+
copy_remote_oscal_component "cg-egress-proxy", "https://raw.githubusercontent.com/GSA-TTS/cg-egress-proxy/refs/heads/main/docs/compliance/component-definitions/cg-egress-proxy/component-definition.json"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
no_tasks do
|
|
92
|
+
def readme_content
|
|
93
|
+
<<~README
|
|
94
|
+
### Public Egress Proxy
|
|
95
|
+
|
|
96
|
+
Traffic to be delivered to the public internet must be proxied through the [cg-egress-proxy](https://github.com/GSA-TTS/cg-egress-proxy) app. Hostnames that the app should be able to
|
|
97
|
+
reach should be added to the `allowlist` terraform configuration in `terraform/staging/main.tf` and `terraform/production/main.tf`
|
|
98
|
+
|
|
99
|
+
See the [ruby troubleshooting doc](https://github.com/GSA-TTS/cg-egress-proxy/blob/main/docs/ruby.md) first if you have any problems making outbound connections through the proxy.
|
|
100
|
+
README
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def terraform_module
|
|
104
|
+
<<~EOT
|
|
105
|
+
|
|
106
|
+
module "egress_space" {
|
|
107
|
+
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
|
|
108
|
+
|
|
109
|
+
cf_org_name = local.cf_org_name
|
|
110
|
+
cf_space_name = "${local.cf_space_name}-egress"
|
|
111
|
+
# deployers should include any user or service account ID that will deploy the egress proxy
|
|
112
|
+
deployers = [
|
|
113
|
+
var.cf_user
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module "egress_proxy" {
|
|
118
|
+
source = "github.com/gsa-tts/terraform-cloudgov//egress_proxy?ref=v1.1.0"
|
|
119
|
+
|
|
120
|
+
cf_org_name = local.cf_org_name
|
|
121
|
+
cf_space_name = module.egress_space.space_name
|
|
122
|
+
client_space = local.cf_space_name
|
|
123
|
+
name = "egress-proxy-${local.env}"
|
|
124
|
+
# comment out allowlist if this module is being deployed before the app has ever been deployed
|
|
125
|
+
allowlist = {
|
|
126
|
+
"${local.app_name}-${local.env}" = []
|
|
127
|
+
}
|
|
128
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
129
|
+
depends_on = [module.app_space, module.egress_space]
|
|
130
|
+
}
|
|
131
|
+
EOT
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -64,7 +64,7 @@ These steps are run once per project.
|
|
|
64
64
|
A [SpaceDeployer](https://cloud.gov/docs/services/cloud-gov-service-account/) account is required to run terraform or
|
|
65
65
|
deploy the application from the CI/CD pipeline. Create a new account by running:
|
|
66
66
|
|
|
67
|
-
`../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME
|
|
67
|
+
`../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m`
|
|
68
68
|
|
|
69
69
|
## Set up a new environment manually
|
|
70
70
|
|
|
@@ -80,7 +80,7 @@ The below steps rely on you first configuring access to the Terraform state in s
|
|
|
80
80
|
# something that communicates the purpose of the deployer
|
|
81
81
|
# for example: circleci-deployer for the credentials CircleCI uses to
|
|
82
82
|
# deploy the application or <your_name>-terraform for credentials to run terraform manually
|
|
83
|
-
../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> > secrets.auto.tfvars
|
|
83
|
+
../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m > secrets.auto.tfvars
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
The script will output the `username` (as `cf_user`) and `password` (as `cf_password`) for your `<ACCOUNT_NAME>`. Read more in the [cloud.gov service account documentation](https://cloud.gov/docs/services/cloud-gov-service-account/).
|
|
@@ -6,7 +6,7 @@ module "s3" {
|
|
|
6
6
|
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.0.0"
|
|
7
7
|
|
|
8
8
|
cf_org_name = "<%= cloud_gov_organization %>"
|
|
9
|
-
cf_space_name = "<%= cloud_gov_production_space
|
|
9
|
+
cf_space_name = "<%= cloud_gov_production_space %>-mgmt"
|
|
10
10
|
name = local.s3_service_name<% if cloud_gov_organization == "sandbox-gsa" %>
|
|
11
11
|
s3_plan_name = "basic-sandbox"<% end %>
|
|
12
12
|
}
|
|
@@ -16,7 +16,8 @@ dig_output () {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if [[ ! -f "secrets.auto.tfvars" ]]; then
|
|
19
|
-
|
|
19
|
+
cf target -s <%= cloud_gov_production_space %>-mgmt || cf create-space <%= cloud_gov_production_space %>-mgmt && cf disallow-space-ssh <%= cloud_gov_production_space %>-mgmt
|
|
20
|
+
../../bin/ops/create_service_account.sh -s <%= cloud_gov_production_space %>-mgmt -u config-bootstrap-deployer > secrets.auto.tfvars
|
|
20
21
|
fi
|
|
21
22
|
|
|
22
23
|
if [[ $# -gt 0 ]]; then
|
data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
../../bin/ops/destroy_service_account.sh -s <%= cloud_gov_production_space
|
|
3
|
+
../../bin/ops/destroy_service_account.sh -s <%= cloud_gov_production_space %>-mgmt -u config-bootstrap-deployer
|
|
4
4
|
|
|
5
5
|
rm secrets.auto.tfvars
|
|
@@ -5,32 +5,48 @@ locals {
|
|
|
5
5
|
app_name = "<%= app_name %>"
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
module "app_space" {
|
|
9
|
+
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
|
|
10
|
+
|
|
11
|
+
cf_org_name = local.cf_org_name
|
|
12
|
+
cf_space_name = local.cf_space_name
|
|
13
|
+
deployers = [var.cf_user]
|
|
14
|
+
# developers should include any users that will potentially need to run `cf ssh` on the app
|
|
15
|
+
developers = []
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
module "database" {
|
|
9
|
-
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.
|
|
19
|
+
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.1.0"
|
|
10
20
|
|
|
11
21
|
cf_org_name = local.cf_org_name
|
|
12
22
|
cf_space_name = local.cf_space_name
|
|
13
23
|
name = "${local.app_name}-rds-${local.env}"
|
|
14
24
|
rds_plan_name = "TKTK-production-rds-plan"
|
|
25
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
26
|
+
depends_on = [module.app_space]
|
|
15
27
|
}
|
|
16
28
|
<% if has_active_job? %>
|
|
17
29
|
module "redis" {
|
|
18
|
-
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.
|
|
30
|
+
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.1.0"
|
|
19
31
|
|
|
20
32
|
cf_org_name = local.cf_org_name
|
|
21
33
|
cf_space_name = local.cf_space_name
|
|
22
34
|
name = "${local.app_name}-redis-${local.env}"
|
|
23
35
|
redis_plan_name = "TKTK-production-redis-plan"
|
|
36
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
37
|
+
depends_on = [module.app_space]
|
|
24
38
|
}
|
|
25
39
|
<% end %>
|
|
26
40
|
<% if has_active_storage? %>
|
|
27
41
|
module "s3" {
|
|
28
|
-
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.
|
|
42
|
+
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.1.0"
|
|
29
43
|
|
|
30
44
|
cf_org_name = local.cf_org_name
|
|
31
45
|
cf_space_name = local.cf_space_name
|
|
32
46
|
name = "${local.app_name}-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
|
|
33
47
|
s3_plan_name = "basic-sandbox"<% end %>
|
|
48
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
49
|
+
depends_on = [module.app_space]
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
###########################################################################
|
|
@@ -40,7 +56,7 @@ module "s3" {
|
|
|
40
56
|
# 2) Your organization has sufficient memory. Each clamav app requires 3GB
|
|
41
57
|
###########################################################################
|
|
42
58
|
# module "clamav" {
|
|
43
|
-
# source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.
|
|
59
|
+
# source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.1.0"
|
|
44
60
|
#
|
|
45
61
|
# cf_org_name = local.cf_org_name
|
|
46
62
|
# cf_space_name = local.cf_space_name
|
|
@@ -48,6 +64,8 @@ module "s3" {
|
|
|
48
64
|
# name = "${local.app_name}-clamapi-${local.env}"
|
|
49
65
|
# clamav_image = "ghcr.io/gsa-tts/clamav-rest/clamav:20240602"
|
|
50
66
|
# max_file_size = "30M"
|
|
67
|
+
# # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
68
|
+
# depends_on = [module.app_space]
|
|
51
69
|
# }
|
|
52
70
|
<% end %>
|
|
53
71
|
|
|
@@ -59,7 +77,7 @@ module "s3" {
|
|
|
59
77
|
# `cf create-domain <%= cloud_gov_organization %> TKTK-production-domain-name`
|
|
60
78
|
###########################################################################
|
|
61
79
|
# module "domain" {
|
|
62
|
-
# source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v1.
|
|
80
|
+
# source = "github.com/gsa-tts/terraform-cloudgov//domain?ref=v1.1.0"
|
|
63
81
|
#
|
|
64
82
|
# cf_org_name = local.cf_org_name
|
|
65
83
|
# cf_space_name = local.cf_space_name
|
|
@@ -67,4 +85,6 @@ module "s3" {
|
|
|
67
85
|
# cdn_plan_name = "domain"
|
|
68
86
|
# domain_name = "TKTK-production-domain-name"
|
|
69
87
|
# host_name = "TKTK-production-hostname (optional)"
|
|
88
|
+
# # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
89
|
+
# depends_on = [module.app_space]
|
|
70
90
|
# }
|
|
@@ -5,32 +5,48 @@ locals {
|
|
|
5
5
|
app_name = "<%= app_name %>"
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
module "app_space" {
|
|
9
|
+
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.1.0"
|
|
10
|
+
|
|
11
|
+
cf_org_name = local.cf_org_name
|
|
12
|
+
cf_space_name = local.cf_space_name
|
|
13
|
+
deployers = [var.cf_user]
|
|
14
|
+
# developers should include any users that will potentially need to run `cf ssh` on the app
|
|
15
|
+
developers = []
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
module "database" {
|
|
9
|
-
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.
|
|
19
|
+
source = "github.com/gsa-tts/terraform-cloudgov//database?ref=v1.1.0"
|
|
10
20
|
|
|
11
21
|
cf_org_name = local.cf_org_name
|
|
12
22
|
cf_space_name = local.cf_space_name
|
|
13
23
|
name = "${local.app_name}-rds-${local.env}"
|
|
14
24
|
rds_plan_name = "micro-psql"
|
|
25
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
26
|
+
depends_on = [module.app_space]
|
|
15
27
|
}
|
|
16
28
|
<% if has_active_job? %>
|
|
17
29
|
module "redis" {
|
|
18
|
-
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.
|
|
30
|
+
source = "github.com/gsa-tts/terraform-cloudgov//redis?ref=v1.1.0"
|
|
19
31
|
|
|
20
32
|
cf_org_name = local.cf_org_name
|
|
21
33
|
cf_space_name = local.cf_space_name
|
|
22
34
|
name = "${local.app_name}-redis-${local.env}"
|
|
23
35
|
redis_plan_name = "redis-dev"
|
|
36
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
37
|
+
depends_on = [module.app_space]
|
|
24
38
|
}
|
|
25
39
|
<% end %>
|
|
26
40
|
<% if has_active_storage? %>
|
|
27
41
|
module "s3" {
|
|
28
|
-
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.
|
|
42
|
+
source = "github.com/gsa-tts/terraform-cloudgov//s3?ref=v1.1.0"
|
|
29
43
|
|
|
30
44
|
cf_org_name = local.cf_org_name
|
|
31
45
|
cf_space_name = local.cf_space_name
|
|
32
46
|
name = "${local.app_name}-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
|
|
33
47
|
s3_plan_name = "basic-sandbox"<% end %>
|
|
48
|
+
# depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
49
|
+
depends_on = [module.app_space]
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
###########################################################################
|
|
@@ -40,7 +56,7 @@ module "s3" {
|
|
|
40
56
|
# 2) Your organization has sufficient memory. Each clamav app requires 3GB
|
|
41
57
|
###########################################################################
|
|
42
58
|
# module "clamav" {
|
|
43
|
-
# source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.
|
|
59
|
+
# source = "github.com/gsa-tts/terraform-cloudgov//clamav?ref=v1.1.0"
|
|
44
60
|
#
|
|
45
61
|
# cf_org_name = local.cf_org_name
|
|
46
62
|
# cf_space_name = local.cf_space_name
|
|
@@ -48,5 +64,7 @@ module "s3" {
|
|
|
48
64
|
# name = "${local.app_name}-clamapi-${local.env}"
|
|
49
65
|
# clamav_image = "ghcr.io/gsa-tts/clamav-rest/clamav:20240602"
|
|
50
66
|
# max_file_size = "30M"
|
|
67
|
+
# # depends_on line is needed only for initial creation and destruction. It should be commented out for updates to prevent unwanted cascading effects
|
|
68
|
+
# depends_on = [module.app_space]
|
|
51
69
|
# }
|
|
52
70
|
<% end %>
|
|
@@ -59,6 +59,13 @@ module RailsTemplate18f
|
|
|
59
59
|
Dir.exist? file_path("doc/compliance/oscal")
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
def copy_remote_oscal_component(component_name, cd_url)
|
|
63
|
+
get cd_url, File.join(oscal_component_path, component_name, "component-definition.json")
|
|
64
|
+
if oscal_dir_exists?
|
|
65
|
+
insert_into_file "doc/compliance/oscal/trestle-config.yaml", " - #{component_name}\n"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
62
69
|
def copy_oscal_component(component_name)
|
|
63
70
|
template "oscal/component-definitions/#{component_name}/component-definition.json",
|
|
64
71
|
File.join(oscal_component_path, component_name, "component-definition.json")
|
|
@@ -4,6 +4,7 @@ module RailsTemplate18f
|
|
|
4
4
|
module Generators
|
|
5
5
|
module CloudGovOptions
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
|
+
include CloudGovParsing
|
|
7
8
|
|
|
8
9
|
included do
|
|
9
10
|
class_option :cg_org, desc: "cloud.gov organization name"
|
|
@@ -14,39 +15,18 @@ module RailsTemplate18f
|
|
|
14
15
|
private
|
|
15
16
|
|
|
16
17
|
def cloud_gov_organization
|
|
17
|
-
if options[:cg_org].present?
|
|
18
|
-
|
|
19
|
-
elsif terraform_dir_exists?
|
|
20
|
-
staging_main = file_content("terraform/staging/main.tf")
|
|
21
|
-
if (matches = staging_main.match(/cf_org_name\s+= "(?<org_name>.*)"/))
|
|
22
|
-
return matches[:org_name]
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
"TKTK-cloud.gov-org-name"
|
|
18
|
+
return options[:cg_org] if options[:cg_org].present?
|
|
19
|
+
super
|
|
26
20
|
end
|
|
27
21
|
|
|
28
22
|
def cloud_gov_staging_space
|
|
29
|
-
if options[:cg_staging].present?
|
|
30
|
-
|
|
31
|
-
elsif terraform_dir_exists?
|
|
32
|
-
staging_main = file_content("terraform/staging/main.tf")
|
|
33
|
-
if (matches = staging_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
34
|
-
return matches[:space_name]
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
"staging"
|
|
23
|
+
return options[:cg_staging] if options[:cg_staging].present?
|
|
24
|
+
super
|
|
38
25
|
end
|
|
39
26
|
|
|
40
27
|
def cloud_gov_production_space
|
|
41
|
-
if options[:cg_prod].present?
|
|
42
|
-
|
|
43
|
-
elsif terraform_dir_exists?
|
|
44
|
-
prod_main = file_content("terraform/production/main.tf")
|
|
45
|
-
if (matches = prod_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
46
|
-
return matches[:space_name]
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
"prod"
|
|
28
|
+
return options[:cg_prod] if options[:cg_prod].present?
|
|
29
|
+
super
|
|
50
30
|
end
|
|
51
31
|
end
|
|
52
32
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsTemplate18f
|
|
4
|
+
module Generators
|
|
5
|
+
module CloudGovParsing
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def cloud_gov_organization
|
|
11
|
+
if terraform_dir_exists?
|
|
12
|
+
staging_main = file_content("terraform/staging/main.tf")
|
|
13
|
+
if (matches = staging_main.match(/cf_org_name\s+= "(?<org_name>.*)"/))
|
|
14
|
+
return matches[:org_name]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
"TKTK-cloud.gov-org-name"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def cloud_gov_staging_space
|
|
21
|
+
if terraform_dir_exists?
|
|
22
|
+
staging_main = file_content("terraform/staging/main.tf")
|
|
23
|
+
if (matches = staging_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
24
|
+
return matches[:space_name]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
"staging"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cloud_gov_production_space
|
|
31
|
+
if terraform_dir_exists?
|
|
32
|
+
prod_main = file_content("terraform/production/main.tf")
|
|
33
|
+
if (matches = prod_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
34
|
+
return matches[:space_name]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
"prod"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/rails-template-18f.gemspec
CHANGED
|
@@ -31,12 +31,12 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
|
|
32
32
|
# For more information and examples about making a new gem, checkout our
|
|
33
33
|
# guide at: https://bundler.io/guides/creating_gem.html
|
|
34
|
-
spec.add_dependency "railties", "~> 7.
|
|
35
|
-
spec.add_dependency "activesupport", "~> 7.
|
|
34
|
+
spec.add_dependency "railties", "~> 7.2.0"
|
|
35
|
+
spec.add_dependency "activesupport", "~> 7.2.0"
|
|
36
36
|
spec.add_dependency "thor", "~> 1.3"
|
|
37
37
|
spec.add_dependency "colorize", "~> 1.1"
|
|
38
38
|
|
|
39
39
|
spec.add_development_dependency "rspec", "~> 3.13"
|
|
40
40
|
spec.add_development_dependency "ammeter", "~> 1.1"
|
|
41
|
-
spec.add_development_dependency "standard", "~> 1.
|
|
41
|
+
spec.add_development_dependency "standard", "~> 1.40"
|
|
42
42
|
end
|
data/railsrc
CHANGED
data/railsrc-hotwire
CHANGED
data/template.rb
CHANGED
|
@@ -39,14 +39,16 @@ def print_announcements
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
unless Gem::Dependency.new("rails", "~> 7.
|
|
43
|
-
warn "This template requires Rails 7.
|
|
42
|
+
unless Gem::Dependency.new("rails", "~> 7.2.0").match?("rails", Rails.gem_version)
|
|
43
|
+
warn "This template requires Rails 7.2.x"
|
|
44
44
|
if Gem::Dependency.new("rails", "~> 6.1.0").match?("rails", Rails.gem_version)
|
|
45
45
|
warn "See the rails-6 branch https://github.com/gsa-tts/rails-template/tree/rails-6"
|
|
46
46
|
elsif Gem::Dependency.new("rails", "~> 7.0.0").match?("rails", Rails.gem_version)
|
|
47
47
|
warn "See the rails-7.0 branch https://github.com/gsa-tts/rails-template/tree/rails-7.0"
|
|
48
|
-
elsif Gem::Dependency.new("rails", "~> 7.
|
|
49
|
-
warn "
|
|
48
|
+
elsif Gem::Dependency.new("rails", "~> 7.1.0").match?("rails", Rails.gem_version)
|
|
49
|
+
warn "See the rails-7.1 branch https://github.com/gsa-tts/rails-template/tree/rails-7.1"
|
|
50
|
+
elsif Gem::Dependency.new("rails", ">= 7.3.0").match?("rails", Rails.gem_version)
|
|
51
|
+
warn "We haven't updated the template for Rails >= 7.3 yet! Please file an issue so we can get the template updated"
|
|
50
52
|
else
|
|
51
53
|
warn "We didn't recognize the version of Rails you are using: #{Rails.version}"
|
|
52
54
|
end
|
|
@@ -71,6 +73,9 @@ if compliance_trestle_submodule && compliance_trestle_repo.blank?
|
|
|
71
73
|
end
|
|
72
74
|
# only ask about auditree if we're also using docker-trestle
|
|
73
75
|
auditree = compliance_trestle ? yes?("Run compliance checks with auditree? (y/n)") : false
|
|
76
|
+
if auditree
|
|
77
|
+
auditree_evidence_repo = ask("What is the https address of your auditree evidence repo? (Leave blank to fill in later)")
|
|
78
|
+
end
|
|
74
79
|
|
|
75
80
|
terraform = yes?("Create terraform files for cloud.gov services? (y/n)")
|
|
76
81
|
@cloud_gov_organization = ask("What is your cloud.gov organization name? (Leave blank to fill in later)")
|
|
@@ -111,9 +116,8 @@ EOM
|
|
|
111
116
|
if compliance_trestle
|
|
112
117
|
after_bundle do
|
|
113
118
|
generator_arguments = []
|
|
114
|
-
if compliance_trestle_submodule
|
|
115
|
-
|
|
116
|
-
end
|
|
119
|
+
generator_arguments << "--oscal_repo=#{compliance_trestle_repo}" if compliance_trestle_submodule
|
|
120
|
+
generator_arguments << "--ci=github" if @github_actions
|
|
117
121
|
generate "rails_template18f:oscal", *generator_arguments
|
|
118
122
|
end
|
|
119
123
|
register_announcement("OSCAL Documentation", <<~EOM)
|
|
@@ -183,7 +187,7 @@ after_bundle do
|
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
# updates for OWASP scan to pass
|
|
186
|
-
gem "secure_headers", "~> 6.
|
|
190
|
+
gem "secure_headers", "~> 6.7"
|
|
187
191
|
initializer "secure_headers.rb", <<~EOM
|
|
188
192
|
SecureHeaders::Configuration.default do |config|
|
|
189
193
|
# CSP settings are handled by Rails
|
|
@@ -224,9 +228,8 @@ uncomment_lines csp_initializer, "content_security_policy_nonce"
|
|
|
224
228
|
gem_group :development, :test do
|
|
225
229
|
gem "rspec-rails", "~> 6.1"
|
|
226
230
|
gem "dotenv-rails", "~> 3.1"
|
|
227
|
-
gem "brakeman", "~> 6.1"
|
|
228
231
|
gem "bundler-audit", "~> 0.9"
|
|
229
|
-
gem "standard", "~> 1.
|
|
232
|
+
gem "standard", "~> 1.40"
|
|
230
233
|
end
|
|
231
234
|
if ENV["RT_DEV"] == "true"
|
|
232
235
|
gem "rails_template_18f", group: :development, path: ENV["PWD"]
|
|
@@ -462,8 +465,11 @@ end
|
|
|
462
465
|
|
|
463
466
|
if auditree
|
|
464
467
|
after_bundle do
|
|
465
|
-
generate "rails_template18f:auditree"
|
|
468
|
+
generate "rails_template18f:auditree", "--evidence_locker=#{auditree_evidence_repo}"
|
|
466
469
|
end
|
|
470
|
+
register_announcement "Auditree", <<~EOM
|
|
471
|
+
* Don't forget to follow the initial setup instructions for Auditree in the main README
|
|
472
|
+
EOM
|
|
467
473
|
end
|
|
468
474
|
|
|
469
475
|
# setup production credentials file
|
|
@@ -495,7 +501,8 @@ EOM
|
|
|
495
501
|
# ensure this is the very last step
|
|
496
502
|
after_bundle do
|
|
497
503
|
if run_db_setup
|
|
498
|
-
rails_command "db:
|
|
504
|
+
rails_command "db:create"
|
|
505
|
+
rails_command "db:migrate"
|
|
499
506
|
end
|
|
500
507
|
|
|
501
508
|
# x86_64-linux is required to install gems on any linux system such as cloud.gov or CI pipelines
|
|
@@ -7,14 +7,18 @@ $0: Create a Service User Account for a given space
|
|
|
7
7
|
|
|
8
8
|
Usage:
|
|
9
9
|
$0 -h
|
|
10
|
-
$0 -s <SPACE NAME> -u <USER NAME> [-r <ROLE NAME>] [-o <ORG NAME>]
|
|
10
|
+
$0 -s <SPACE NAME> -u <USER NAME> [-r <ROLE NAME>] [-o <ORG NAME>] [-m]
|
|
11
11
|
|
|
12
12
|
Options:
|
|
13
13
|
-h: show help and exit
|
|
14
14
|
-s <SPACE NAME>: configure the space to act on. Required
|
|
15
15
|
-u <USER NAME>: set the service user name. Required
|
|
16
16
|
-r <ROLE NAME>: set the service user's role to either space-deployer or space-auditor. Default: space-deployer
|
|
17
|
+
-m: If provided, make the service user an OrgManager
|
|
17
18
|
-o <ORG NAME>: configure the organization to act on. Default: $org
|
|
19
|
+
|
|
20
|
+
Notes:
|
|
21
|
+
* OrgManager is required for terraform to create <env>-egress spaces
|
|
18
22
|
"
|
|
19
23
|
|
|
20
24
|
set -e
|
|
@@ -23,8 +27,9 @@ set -o pipefail
|
|
|
23
27
|
space=""
|
|
24
28
|
service=""
|
|
25
29
|
role="space-deployer"
|
|
30
|
+
org_manager="false"
|
|
26
31
|
|
|
27
|
-
while getopts ":
|
|
32
|
+
while getopts ":hms:u:r:o:" opt; do
|
|
28
33
|
case "$opt" in
|
|
29
34
|
s)
|
|
30
35
|
space=${OPTARG}
|
|
@@ -38,6 +43,9 @@ while getopts ":hs:u:r:o:" opt; do
|
|
|
38
43
|
o)
|
|
39
44
|
org=${OPTARG}
|
|
40
45
|
;;
|
|
46
|
+
m)
|
|
47
|
+
org_manager="true"
|
|
48
|
+
;;
|
|
41
49
|
h)
|
|
42
50
|
echo "$usage"
|
|
43
51
|
exit 0
|
|
@@ -69,6 +77,10 @@ creds=`cf service-key $service service-account-key | tail -n +2 | jq '.credentia
|
|
|
69
77
|
username=`echo $creds | jq -r '.username'`
|
|
70
78
|
password=`echo $creds | jq -r '.password'`
|
|
71
79
|
|
|
80
|
+
if [[ "$org_manager" = "true" ]]; then
|
|
81
|
+
cf set-org-role $username $org OrgManager 1>&2
|
|
82
|
+
fi
|
|
83
|
+
|
|
72
84
|
cat << EOF
|
|
73
85
|
# generated with $0 -s $space -u $service -r $role -o $org
|
|
74
86
|
# revoke with $(dirname $0)/destroy_service_account.sh -s $space -u $service -o $org
|
|
@@ -2,7 +2,7 @@ desc "Run brakeman with potential non-0 return code"
|
|
|
2
2
|
task :brakeman do
|
|
3
3
|
# -z flag makes it return non-0 if there are any warnings
|
|
4
4
|
# -q quiets output
|
|
5
|
-
unless system("brakeman -z -q") # system is true if return is 0, false otherwise
|
|
5
|
+
unless system("bin/brakeman -z -q") # system is true if return is 0, false otherwise
|
|
6
6
|
abort("Brakeman detected one or more code problems, please run it manually and inspect the output.")
|
|
7
7
|
end
|
|
8
8
|
end
|