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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/Gemfile.lock +57 -55
  4. data/README.md +102 -29
  5. data/exe/rails_template_18f +0 -21
  6. data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +2 -2
  7. data/lib/generators/rails_template18f/auditree/auditree_generator.rb +34 -3
  8. data/lib/generators/rails_template18f/auditree/templates/bin/auditree.tt +85 -11
  9. data/lib/generators/rails_template18f/auditree/templates/github/actions/auditree-cmd/action.yml.tt +17 -6
  10. data/lib/generators/rails_template18f/auditree/templates/github/workflows/auditree-validation.yml.tt +2 -6
  11. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +13 -7
  12. data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +1 -1
  13. data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +0 -1
  14. data/lib/generators/rails_template18f/github_actions/templates/github/dependabot.yml.tt +25 -0
  15. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/assemble-ssp.yml.tt +12 -3
  16. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/brakeman-analysis.yml +1 -1
  17. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +8 -0
  18. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +8 -0
  19. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/rspec.yml.tt +9 -1
  20. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/{validate-ssp.yml.tt → validate-ssp.yml} +1 -1
  21. data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +12 -20
  22. data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js +11 -0
  23. data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +4 -0
  24. data/lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb +5 -0
  25. data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +8 -7
  26. data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +1 -1
  27. data/lib/generators/rails_template18f/oscal/oscal_generator.rb +14 -1
  28. data/lib/generators/rails_template18f/oscal/templates/bin/trestle.tt +4 -1
  29. data/lib/generators/rails_template18f/oscal/templates/github/actions/trestle-cmd/action.yml.tt +16 -0
  30. data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +136 -0
  31. data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +1 -1
  32. data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +2 -2
  33. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +1 -1
  34. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +2 -1
  35. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +1 -1
  36. data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +25 -5
  37. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +22 -4
  38. data/lib/rails_template18f/generators/base.rb +7 -0
  39. data/lib/rails_template18f/generators/cloud_gov_options.rb +7 -27
  40. data/lib/rails_template18f/generators/cloud_gov_parsing.rb +41 -0
  41. data/lib/rails_template18f/generators.rb +1 -0
  42. data/lib/rails_template18f/version.rb +1 -1
  43. data/rails-template-18f.gemspec +3 -3
  44. data/railsrc +2 -0
  45. data/railsrc-hotwire +2 -0
  46. data/template.rb +19 -12
  47. data/templates/bin/ops/create_service_account.sh.tt +14 -2
  48. data/templates/bin/ops/destroy_service_account.sh.tt +0 -3
  49. data/templates/lib/tasks/scanning.rake +1 -1
  50. data/templates/manifest.yml.tt +1 -1
  51. metadata +19 -14
  52. data/lib/generators/rails_template18f/github_actions/templates/github/actions/trestle-cmd/action.yml +0 -20
  53. data/lib/rails_template18f/app_updater.rb +0 -19
  54. /data/lib/generators/rails_template18f/terraform/templates/terraform/production/{providers.tf.tt → providers.tf} +0 -0
  55. /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
@@ -14,7 +14,7 @@ module RailsTemplate18f
14
14
 
15
15
  def install_gem
16
16
  return if gem_installed?("sidekiq")
17
- gem "sidekiq", "~> 7.2"
17
+ gem "sidekiq", "~> 7.3"
18
18
  bundle_install
19
19
  end
20
20
 
@@ -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
- ../../bin/ops/create_service_account.sh -s <%= cloud_gov_production_space %> -u config-bootstrap-deployer > secrets.auto.tfvars
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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- ../../bin/ops/destroy_service_account.sh -s <%= cloud_gov_production_space %> -u config-bootstrap-deployer
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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.0.0"
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
- return options[:cg_org]
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
- return options[:cg_staging]
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
- return options[:cg_prod]
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
@@ -6,6 +6,7 @@ module RailsTemplate18f
6
6
 
7
7
  autoload :Base
8
8
  autoload :CloudGovOptions
9
+ autoload :CloudGovParsing
9
10
  autoload :PipelineOptions
10
11
  end
11
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsTemplate18f
4
- VERSION = "1.1.0"
4
+ VERSION = "1.3.0"
5
5
  end
@@ -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.1.0"
35
- spec.add_dependency "activesupport", "~> 7.1.0"
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.36"
41
+ spec.add_development_dependency "standard", "~> 1.40"
42
42
  end
data/railsrc CHANGED
@@ -9,3 +9,5 @@
9
9
  --css=postcss
10
10
  --template=template.rb
11
11
  --database=postgresql
12
+ --skip-rubocop
13
+ --skip-ci
data/railsrc-hotwire CHANGED
@@ -7,3 +7,5 @@
7
7
  --css=postcss
8
8
  --template=template.rb
9
9
  --database=postgresql
10
+ --skip-rubocop
11
+ --skip-ci
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.1.0").match?("rails", Rails.gem_version)
43
- warn "This template requires Rails 7.1.x"
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.2.0").match?("rails", Rails.gem_version)
49
- warn "We haven't updated the template for Rails 7.2 yet! Please file an issue so we can get the template updated"
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
- generator_arguments << "--oscal_repo=#{compliance_trestle_repo}"
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.3"
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.36"
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:setup"
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 ":hs:u:r:o:" opt; do
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
@@ -46,8 +46,5 @@ fi
46
46
 
47
47
  cf target -o $org -s $space
48
48
 
49
- # destroy service key
50
- cf delete-service-key $service service-account-key -f
51
-
52
49
  # destroy service
53
50
  cf delete-service $service -f
@@ -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