rails_template_18f 1.2.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 (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +29 -31
  4. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +5 -0
  5. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +8 -0
  6. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +8 -0
  7. data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +12 -20
  8. data/lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js +11 -0
  9. data/lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml +4 -0
  10. data/lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb +5 -0
  11. data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +8 -7
  12. data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +136 -0
  13. data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +2 -2
  14. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/main.tf.tt +1 -1
  15. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/run.sh.tt +2 -1
  16. data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +1 -1
  17. data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +25 -5
  18. data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +22 -4
  19. data/lib/rails_template18f/generators/base.rb +7 -0
  20. data/lib/rails_template18f/generators/cloud_gov_options.rb +7 -27
  21. data/lib/rails_template18f/generators/cloud_gov_parsing.rb +41 -0
  22. data/lib/rails_template18f/generators.rb +1 -0
  23. data/lib/rails_template18f/version.rb +1 -1
  24. data/templates/bin/ops/create_service_account.sh.tt +14 -2
  25. data/templates/bin/ops/destroy_service_account.sh.tt +0 -3
  26. data/templates/manifest.yml.tt +1 -1
  27. metadata +9 -4
  28. /data/lib/generators/rails_template18f/terraform/templates/terraform/production/{providers.tf.tt → providers.tf} +0 -0
  29. /data/lib/generators/rails_template18f/terraform/templates/terraform/staging/{providers.tf.tt → providers.tf} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 957ad56e218689b3d05f7c31ae6354a4e2c42877567ea87478845b30129cef43
4
- data.tar.gz: f5d6045a2632863b50209c557f7460f61f9bacb90a99883b6b090f6580c528d0
3
+ metadata.gz: 24d43ee8d10fdaa457658cfab2ce12e28e9d65364147ad46e96ef8d8d2f6f15c
4
+ data.tar.gz: 686546614e2d8205fce7ccd575842645effeb30add6d08fe3057b6623f1800f6
5
5
  SHA512:
6
- metadata.gz: ea0332afd7b819bcd2b03acca406467f9404de6f8e065e980bdabf81ef7083377f8dfc4d6754baaf1a4e6525eaa5190402f7a5307d35fb472960089a62ddba9e
7
- data.tar.gz: 5720c1340a3065354de210dd4deccb5577656876501514ac09faf91a133511e92796e0cb18aee299e8894b16394fbacde12419e6c97795a3be086242e9afa815
6
+ metadata.gz: ebc79caba4f53280dbf1dffa76ba9268ecbd6ae9634fd463f1920770a02531f0d5cd350a26ecbc439accf57fbe96d824e76349ce29492075fb2d4151b40cd46a
7
+ data.tar.gz: 79fa51828475fac62b1a5e4ec4562eb9b563da24760f85c41c42f123bdb3e882124a38686050a52c0c6b3ffa29577eaa547405e78ef14ad1b6b99f7fff5df0e8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.3.0] - 2024-12-18
4
+
5
+ - Set up app space via terraform, with proper restricted egress security group
6
+ - Create rails_template18f:public_egress generator for integrating with cg-egress-proxy
7
+ - [Use exec when starting rails server](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#start-commands:~:text=To%20resolve%20this,process.%20For%20example%3A)
8
+ - Upgrade the i18n-js integration to 4.x
9
+
3
10
  ## [1.2.0] - 2024-09-20
4
11
 
5
12
  - new applications are now on Rails 7.2.x
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_template_18f (1.2.0)
4
+ rails_template_18f (1.3.0)
5
5
  activesupport (~> 7.2.0)
6
6
  colorize (~> 1.1)
7
7
  railties (~> 7.2.0)
@@ -10,9 +10,9 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actionpack (7.2.0)
14
- actionview (= 7.2.0)
15
- activesupport (= 7.2.0)
13
+ actionpack (7.2.1)
14
+ actionview (= 7.2.1)
15
+ activesupport (= 7.2.1)
16
16
  nokogiri (>= 1.8.5)
17
17
  racc
18
18
  rack (>= 2.2.4, < 3.2)
@@ -21,13 +21,13 @@ GEM
21
21
  rails-dom-testing (~> 2.2)
22
22
  rails-html-sanitizer (~> 1.6)
23
23
  useragent (~> 0.16)
24
- actionview (7.2.0)
25
- activesupport (= 7.2.0)
24
+ actionview (7.2.1)
25
+ activesupport (= 7.2.1)
26
26
  builder (~> 3.1)
27
27
  erubi (~> 1.11)
28
28
  rails-dom-testing (~> 2.2)
29
29
  rails-html-sanitizer (~> 1.6)
30
- activesupport (7.2.0)
30
+ activesupport (7.2.1)
31
31
  base64
32
32
  bigdecimal
33
33
  concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -54,16 +54,16 @@ GEM
54
54
  diff-lcs (1.5.1)
55
55
  drb (2.2.1)
56
56
  erubi (1.13.0)
57
- i18n (1.14.5)
57
+ i18n (1.14.6)
58
58
  concurrent-ruby (~> 1.0)
59
59
  io-console (0.7.2)
60
- irb (1.14.0)
60
+ irb (1.14.1)
61
61
  rdoc (>= 4.0.0)
62
62
  reline (>= 0.4.2)
63
63
  json (2.7.2)
64
64
  language_server-protocol (3.17.0.3)
65
65
  lint_roller (1.1.0)
66
- logger (1.6.0)
66
+ logger (1.6.1)
67
67
  loofah (2.22.0)
68
68
  crass (~> 1.0.2)
69
69
  nokogiri (>= 1.12.0)
@@ -75,7 +75,7 @@ GEM
75
75
  nokogiri (1.16.7-x86_64-linux)
76
76
  racc (~> 1.4)
77
77
  parallel (1.26.3)
78
- parser (3.3.4.2)
78
+ parser (3.3.5.0)
79
79
  ast (~> 2.4.1)
80
80
  racc
81
81
  psych (5.1.2)
@@ -96,9 +96,9 @@ GEM
96
96
  rails-html-sanitizer (1.6.0)
97
97
  loofah (~> 2.21)
98
98
  nokogiri (~> 1.14)
99
- railties (7.2.0)
100
- actionpack (= 7.2.0)
101
- activesupport (= 7.2.0)
99
+ railties (7.2.1)
100
+ actionpack (= 7.2.1)
101
+ activesupport (= 7.2.1)
102
102
  irb (~> 1.13)
103
103
  rackup (>= 1.0.0)
104
104
  rake (>= 12.2)
@@ -109,26 +109,25 @@ GEM
109
109
  rdoc (6.7.0)
110
110
  psych (>= 4.0.0)
111
111
  regexp_parser (2.9.2)
112
- reline (0.5.9)
112
+ reline (0.5.10)
113
113
  io-console (~> 0.5)
114
- rexml (3.3.6)
115
- strscan
114
+ rexml (3.3.8)
116
115
  rspec (3.13.0)
117
116
  rspec-core (~> 3.13.0)
118
117
  rspec-expectations (~> 3.13.0)
119
118
  rspec-mocks (~> 3.13.0)
120
- rspec-core (3.13.0)
119
+ rspec-core (3.13.1)
121
120
  rspec-support (~> 3.13.0)
122
- rspec-expectations (3.13.2)
121
+ rspec-expectations (3.13.3)
123
122
  diff-lcs (>= 1.2.0, < 2.0)
124
123
  rspec-support (~> 3.13.0)
125
- rspec-mocks (3.13.1)
124
+ rspec-mocks (3.13.2)
126
125
  diff-lcs (>= 1.2.0, < 2.0)
127
126
  rspec-support (~> 3.13.0)
128
- rspec-rails (6.1.4)
129
- actionpack (>= 6.1)
130
- activesupport (>= 6.1)
131
- railties (>= 6.1)
127
+ rspec-rails (7.0.1)
128
+ actionpack (>= 7.0)
129
+ activesupport (>= 7.0)
130
+ railties (>= 7.0)
132
131
  rspec-core (~> 3.13)
133
132
  rspec-expectations (~> 3.13)
134
133
  rspec-mocks (~> 3.13)
@@ -145,14 +144,14 @@ GEM
145
144
  rubocop-ast (>= 1.31.1, < 2.0)
146
145
  ruby-progressbar (~> 1.7)
147
146
  unicode-display_width (>= 2.4.0, < 3.0)
148
- rubocop-ast (1.32.1)
147
+ rubocop-ast (1.32.3)
149
148
  parser (>= 3.3.1.0)
150
149
  rubocop-performance (1.21.1)
151
150
  rubocop (>= 1.48.1, < 2.0)
152
151
  rubocop-ast (>= 1.31.1, < 2.0)
153
152
  ruby-progressbar (1.13.0)
154
153
  securerandom (0.3.1)
155
- standard (1.40.0)
154
+ standard (1.40.1)
156
155
  language_server-protocol (~> 3.17.0.2)
157
156
  lint_roller (~> 1.0)
158
157
  rubocop (~> 1.65.0)
@@ -165,14 +164,13 @@ GEM
165
164
  lint_roller (~> 1.1)
166
165
  rubocop-performance (~> 1.21.0)
167
166
  stringio (3.1.1)
168
- strscan (3.1.0)
169
- thor (1.3.1)
167
+ thor (1.3.2)
170
168
  tzinfo (2.0.6)
171
169
  concurrent-ruby (~> 1.0)
172
- unicode-display_width (2.5.0)
170
+ unicode-display_width (2.6.0)
173
171
  useragent (0.16.10)
174
- webrick (1.8.1)
175
- zeitwerk (2.6.17)
172
+ webrick (1.8.2)
173
+ zeitwerk (2.6.18)
176
174
 
177
175
  PLATFORMS
178
176
  arm64-darwin-23
@@ -71,6 +71,11 @@ commands:
71
71
  -p ${<< parameters.cloudgov_password >>} \
72
72
  -o << parameters.cloudgov_org >> \
73
73
  -s << parameters.cloudgov_space >>
74
+ - run:
75
+ name: Set restricted egress
76
+ command: |
77
+ cf bind-security-group trusted_local_networks_egress << parameters.cloudgov_org >> \
78
+ --space << parameters.cloudgov_space >>
74
79
  - run:
75
80
  name: Push application with deployment vars
76
81
  command: |
@@ -32,6 +32,14 @@ jobs:
32
32
  access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
33
33
  secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
34
34
  <% end %>
35
+ - name: Set restricted egress
36
+ uses: cloud-gov/cg-cli-tools@main
37
+ with:
38
+ cf_username: ${{ secrets.CF_USERNAME }}
39
+ cf_password: ${{ secrets.CF_PASSWORD }}
40
+ cf_org: <%= cloud_gov_organization %>
41
+ cf_space: <%= cloud_gov_production_space %>
42
+ cf_command: bind-security-group trusted_local_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
35
43
  - name: Deploy app
36
44
  uses: cloud-gov/cg-cli-tools@main
37
45
  with:
@@ -32,6 +32,14 @@ jobs:
32
32
  access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
33
33
  secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
34
34
  <% end %>
35
+ - name: Set restricted egress
36
+ uses: cloud-gov/cg-cli-tools@main
37
+ with:
38
+ cf_username: ${{ secrets.CF_USERNAME }}
39
+ cf_password: ${{ secrets.CF_PASSWORD }}
40
+ cf_org: <%= cloud_gov_organization %>
41
+ cf_space: <%= cloud_gov_staging_space %>
42
+ cf_command: bind-security-group trusted_local_networks_egress $INPUT_CF_ORG --space $INPUT_CF_SPACE
35
43
  - name: Deploy app
36
44
  uses: cloud-gov/cg-cli-tools@main
37
45
  with:
@@ -12,37 +12,29 @@ module RailsTemplate18f
12
12
  Install and configure i18n-js gem to provide translations to JS code.
13
13
 
14
14
  By default, will only export translations with keys that match `*.js.*`
15
+
16
+ To use, add the following to your js code:
17
+
18
+ 1. `import { i18n } from './i18n';`
19
+ 2. `i18n.t('path.to.translation.key')`
15
20
  DESC
16
21
 
17
- def install_gem_and_tasks
18
- return if gem_installed?("i18n-js")
19
- gem "i18n-js", "~> 3.9"
22
+ def install_gems
23
+ gem "i18n-js", "~> 4.2" unless gem_installed?("i18n-js")
24
+ gem "listen", "~> 3.9", group: :development unless gem_installed?("listen")
20
25
  bundle_install do
21
26
  run "yarn add i18n-js"
22
- generate "i18n:js:config"
23
27
  end
24
28
  end
25
29
 
26
30
  def configure_translation_yaml
27
- append_to_file "config/i18n-js.yml", <<~EOYAML
28
- # remove `only` to include all translations
29
- translations:
30
- - file: "app/assets/builds/translations.js"
31
- only: "*.js.*"
32
- EOYAML
31
+ copy_file "config/i18n-js.yml"
33
32
  end
34
33
 
35
34
  def configure_asset_pipeline
36
35
  copy_file "lib/tasks/i18n.rake"
37
- environment "config.middleware.use I18n::JS::Middleware", env: :development
38
- insert_into_file "app/views/layouts/application.html.erb", indent(<<~EOHTML, 4), after: /<%= stylesheet_link_tag "application".*$\n/
39
- <%= javascript_include_tag "i18n", "data-turbo-track": "reload" %>
40
- <%= javascript_include_tag "translations", "data-turbo-track": "reload" %>
41
- EOHTML
42
- append_to_file "app/assets/config/manifest.js", <<~EOJS
43
- //= link i18n.js
44
- //= link translations.js
45
- EOJS
36
+ copy_file "config/initializers/i18n_js.rb"
37
+ copy_file "app/javascript/i18n.js"
46
38
  end
47
39
 
48
40
  def ignore_generated_file
@@ -50,7 +42,7 @@ module RailsTemplate18f
50
42
  append_to_file ".gitignore", <<~EOM
51
43
 
52
44
  # Generated by i18n-js
53
- /public/javascripts/i18n.js
45
+ /app/javascript/generated
54
46
  EOM
55
47
  end
56
48
  end
@@ -0,0 +1,11 @@
1
+ import { I18n } from 'i18n-js';
2
+ import translations from './generated/translations.json';
3
+
4
+ const userLocale = document.documentElement.lang;
5
+
6
+ export const i18n = new I18n();
7
+
8
+ i18n.store(translations);
9
+ i18n.defaultLocale = "en";
10
+ i18n.enableFallback = true;
11
+ i18n.locale = userLocale;
@@ -0,0 +1,4 @@
1
+ translations:
2
+ - file: "app/javascript/generated/translations.json"
3
+ patterns:
4
+ - "*.js.*"
@@ -0,0 +1,5 @@
1
+ Rails.application.config.after_initialize do
2
+ require "i18n-js/listen"
3
+ # This will only run in development
4
+ I18nJS.listen config_file: Rails.root.join("config/i18n-js.yml")
5
+ end
@@ -1,9 +1,10 @@
1
1
  # export translations as part of asset precompile
2
-
3
- Rake::Task["assets:precompile"].enhance(["i18n:js:export"])
4
-
5
- if Rake::Task.task_defined?("test:prepare")
6
- Rake::Task["test:prepare"].enhance(["i18n:js:export"])
7
- elsif Rake::Task.task_defined?("db:test:prepare")
8
- Rake::Task["db:test:prepare"].enhance(["i18n:js:export"])
2
+ namespace "i18n:js" do
3
+ desc "Call the i18n-js export method"
4
+ task :export do
5
+ require "i18n-js"
6
+ I18nJS.call(config_file: "config/i18n-js.yml")
7
+ end
9
8
  end
9
+
10
+ Rake::Task["javascript:build"].enhance(["i18n:js:export"])
@@ -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
- ../../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.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
@@ -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
@@ -12,6 +12,6 @@ applications:
12
12
  - type: web
13
13
  instances: ((web_instances))
14
14
  memory: ((web_memory))
15
- command: bundle exec rake cf:on_first_instance db:migrate && bundle exec rails s -b 0.0.0.0 -p $PORT -e $RAILS_ENV
15
+ command: bundle exec rake cf:on_first_instance db:migrate && exec bundle exec rails s -b 0.0.0.0 -p $PORT -e $RAILS_ENV
16
16
  services:
17
17
  - <%= app_name %>-rds-((env))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_template_18f
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ahearn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-20 00:00:00.000000000 Z
11
+ date: 2024-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -174,6 +174,9 @@ files:
174
174
  - lib/generators/rails_template18f/i18n/templates/config/locales/fr.yml
175
175
  - lib/generators/rails_template18f/i18n/templates/config/locales/zh.yml
176
176
  - lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb
177
+ - lib/generators/rails_template18f/i18n_js/templates/app/javascript/i18n.js
178
+ - lib/generators/rails_template18f/i18n_js/templates/config/i18n-js.yml
179
+ - lib/generators/rails_template18f/i18n_js/templates/config/initializers/i18n_js.rb
177
180
  - lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake
178
181
  - lib/generators/rails_template18f/newrelic/newrelic_generator.rb
179
182
  - lib/generators/rails_template18f/newrelic/templates/config/newrelic.yml.tt
@@ -182,6 +185,7 @@ files:
182
185
  - lib/generators/rails_template18f/oscal/templates/bin/trestle.tt
183
186
  - lib/generators/rails_template18f/oscal/templates/doc/compliance/oscal/trestle-config.yaml.tt
184
187
  - lib/generators/rails_template18f/oscal/templates/github/actions/trestle-cmd/action.yml.tt
188
+ - lib/generators/rails_template18f/public_egress/public_egress_generator.rb
185
189
  - lib/generators/rails_template18f/rails_erd/rails_erd_generator.rb
186
190
  - lib/generators/rails_template18f/rails_erd/templates/erdconfig
187
191
  - lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb
@@ -194,15 +198,16 @@ files:
194
198
  - lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt
195
199
  - lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/variables.tf
196
200
  - lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt
197
- - lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf.tt
201
+ - lib/generators/rails_template18f/terraform/templates/terraform/production/providers.tf
198
202
  - lib/generators/rails_template18f/terraform/templates/terraform/production/variables.tf
199
203
  - lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt
200
- - lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf.tt
204
+ - lib/generators/rails_template18f/terraform/templates/terraform/staging/providers.tf
201
205
  - lib/generators/rails_template18f/terraform/templates/terraform/staging/variables.tf
202
206
  - lib/generators/rails_template18f/terraform/terraform_generator.rb
203
207
  - lib/rails_template18f/generators.rb
204
208
  - lib/rails_template18f/generators/base.rb
205
209
  - lib/rails_template18f/generators/cloud_gov_options.rb
210
+ - lib/rails_template18f/generators/cloud_gov_parsing.rb
206
211
  - lib/rails_template18f/generators/pipeline_options.rb
207
212
  - lib/rails_template18f/version.rb
208
213
  - lib/rails_template_18f.rb