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.
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