rails_template_18f 1.1.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|