rails_template_18f 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -1
- data/README.md +16 -19
- data/exe/rails_template_18f +60 -0
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +135 -0
- data/lib/generators/rails_template18f/active_storage/templates/app/jobs/file_scan_job.rb +33 -0
- data/lib/generators/rails_template18f/active_storage/templates/app/models/file_upload.rb +25 -0
- data/lib/generators/rails_template18f/active_storage/templates/doc/adr/clamav.md.tt +30 -0
- data/lib/generators/rails_template18f/active_storage/templates/spec/jobs/file_scan_job_spec.rb +35 -0
- data/lib/generators/rails_template18f/active_storage/templates/spec/models/file_upload_spec.rb +38 -0
- data/lib/generators/rails_template18f/circleci/circleci_generator.rb +26 -10
- data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +28 -0
- data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +15 -0
- data/lib/generators/rails_template18f/cloud_gov_config/templates/spec/models/cloud_gov_config_spec.rb +44 -0
- data/lib/generators/rails_template18f/dap/dap_generator.rb +72 -0
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +27 -11
- data/lib/generators/rails_template18f/i18n/i18n_generator.rb +107 -0
- data/{templates → lib/generators/rails_template18f/i18n/templates}/config/locales/en.yml.tt +3 -3
- data/{templates → lib/generators/rails_template18f/i18n/templates}/config/locales/es.yml +3 -3
- data/{templates → lib/generators/rails_template18f/i18n/templates}/config/locales/fr.yml +3 -6
- data/{templates → lib/generators/rails_template18f/i18n/templates}/config/locales/zh.yml +0 -0
- data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +60 -0
- data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +9 -0
- data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +79 -0
- data/{templates/config/newrelic.yml → lib/generators/rails_template18f/newrelic/templates/config/newrelic.yml.tt} +7 -7
- data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +70 -0
- data/lib/generators/rails_template18f/sidekiq/templates/config/initializers/redis.rb +14 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/README.md.tt +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/bootstrap/import.sh +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/bootstrap/main.tf.tt +3 -3
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/bootstrap/providers.tf +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/bootstrap/run.sh.tt +1 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/teardown_creds.sh.tt +5 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/bootstrap/variables.tf +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/create_space_deployer.sh +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/destroy_space_deployer.sh +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +82 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/production/providers.tf.tt +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/production/variables.tf +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/main.tf.tt +50 -0
- data/{templates/terraform/shared/database → lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav}/providers.tf +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/variables.tf +47 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/database/main.tf.tt +0 -0
- data/{templates/terraform/shared/domain → lib/generators/rails_template18f/terraform/templates/terraform/shared/database}/providers.tf +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/database/variables.tf +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/domain/main.tf.tt +1 -1
- data/{templates/terraform/shared/s3 → lib/generators/rails_template18f/terraform/templates/terraform/shared/domain}/providers.tf +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/domain/variables.tf +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/main.tf.tt +23 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/providers.tf +16 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/variables.tf +42 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/s3/main.tf +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/s3/providers.tf +16 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/shared/s3/variables.tf +0 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +62 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/staging/providers.tf.tt +0 -0
- data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/staging/variables.tf +0 -0
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +84 -0
- data/lib/rails_template18f/app_updater.rb +19 -0
- data/lib/rails_template18f/generators/base.rb +53 -0
- data/lib/rails_template18f/generators/cloud_gov_options.rb +53 -0
- data/lib/rails_template18f/generators/pipeline_options.rb +18 -0
- data/lib/rails_template18f/generators.rb +11 -0
- data/lib/rails_template18f/version.rb +1 -1
- data/lib/rails_template_18f.rb +1 -4
- data/rails-template-18f.gemspec +1 -0
- data/template.rb +84 -148
- data/templates/README.md.tt +7 -44
- data/templates/config/deployment/staging.yml +1 -1
- data/templates/config/environments/ci.rb +0 -1
- data/templates/doc/compliance/apps/application.boundary.md.tt +4 -31
- data/templates/githooks/{pre-commit.tt → pre-commit} +0 -15
- data/templates/manifest.yml.tt +1 -2
- metadata +77 -34
- data/lib/rails_template18f/terraform_options.rb +0 -68
- data/templates/terraform/bootstrap/teardown_creds.sh.tt +0 -5
- data/templates/terraform/production/main.tf.tt +0 -50
- data/templates/terraform/staging/main.tf.tt +0 -30
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe CloudGovConfig, type: :model do
|
|
6
|
+
subject { described_class }
|
|
7
|
+
|
|
8
|
+
describe ".dig" do
|
|
9
|
+
context "VCAP_SERVICES is blank" do
|
|
10
|
+
it "returns nil" do
|
|
11
|
+
expect(subject.dig(:s3, :credentials, :bucket)).to be_nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context "VCAP_SERVICES is set" do
|
|
16
|
+
let(:bucket_name) { "bucket-name" }
|
|
17
|
+
let(:vcap) {
|
|
18
|
+
{
|
|
19
|
+
s3: [
|
|
20
|
+
{
|
|
21
|
+
credentials: {
|
|
22
|
+
bucket: bucket_name
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
around do |example|
|
|
30
|
+
ClimateControl.modify VCAP_SERVICES: vcap.to_json do
|
|
31
|
+
example.run
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "can find a path" do
|
|
36
|
+
expect(subject.dig(:s3, :credentials, :bucket)).to eq bucket_name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "returns nil for a missing path" do
|
|
40
|
+
expect(subject.dig(:s3, :credentials, :other)).to be_nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module RailsTemplate18f
|
|
6
|
+
module Generators
|
|
7
|
+
class DapGenerator < ::Rails::Generators::Base
|
|
8
|
+
include Base
|
|
9
|
+
|
|
10
|
+
class_option :agency_code, default: "GSA", desc: "Agency code to track DAP metrics"
|
|
11
|
+
|
|
12
|
+
desc <<~DESC
|
|
13
|
+
Description:
|
|
14
|
+
Install JS snippet for Digital Analytics Program (DAP)
|
|
15
|
+
DESC
|
|
16
|
+
|
|
17
|
+
def update_content_security_policy
|
|
18
|
+
csp_file = "config/initializers/content_security_policy.rb"
|
|
19
|
+
gsub_file csp_file, /(policy.img_src .*)$/, '\1, "https://www.google-analytics.com"'
|
|
20
|
+
gsub_file csp_file, /(policy.script_src .*)$/, '\1, "https://dap.digitalgov.gov", "https://www.google-analytics.com"'
|
|
21
|
+
if file_content(csp_file).match?(/policy.connect_src/)
|
|
22
|
+
gsub_file csp_file, /(policy.connect_src .*)$/, '\1, "https://dap.digitalgov.gov", "https://www.google-analytics.com"'
|
|
23
|
+
else
|
|
24
|
+
gsub_file csp_file, /((#?)(\s+)policy.script_src .*)$/, "\\1\n\\2\\3policy.connect_src :self, \"https://dap.digitalgov.gov\", \"https://www.google-analytics.com\""
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def install_js_snippet
|
|
29
|
+
insert_into_file "app/views/layouts/application.html.erb", <<EODAP, before: /^\s+<\/head>/
|
|
30
|
+
|
|
31
|
+
<% if Rails.env.production? %>
|
|
32
|
+
<!-- We participate in the US government's analytics program. See the data at analytics.usa.gov. -->
|
|
33
|
+
<%= javascript_include_tag "https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js?agency=#{options[:agency_code]}", async: true, id:"_fed_an_ua_tag" %>
|
|
34
|
+
<% end %>
|
|
35
|
+
EODAP
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def update_readme
|
|
39
|
+
insertion_regex = /^## Documentation$/
|
|
40
|
+
if file_content("README.md").match?(insertion_regex)
|
|
41
|
+
insert_into_file "README.md", readme, before: insertion_regex
|
|
42
|
+
else
|
|
43
|
+
append_to_file "README.md", readme
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def update_boundary_diagram
|
|
48
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
|
49
|
+
insert_into_file boundary_filename, <<EOB, after: "Boundary(gsa_saas, \"GSA-authorized SaaS\") {\n"
|
|
50
|
+
System_Ext(dap, "DAP", "Analytics collection")
|
|
51
|
+
EOB
|
|
52
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
|
53
|
+
Rel(browser, dap, "reports usage", "https (443)")
|
|
54
|
+
Rel(developer, dap, "View traffic statistics", "https GET (443)")
|
|
55
|
+
EOB
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
no_tasks do
|
|
59
|
+
def readme
|
|
60
|
+
<<~EOM
|
|
61
|
+
## Analytics
|
|
62
|
+
|
|
63
|
+
Digital Analytics Program (DAP) code has been included for the Production environment, associated with #{options[:agency_code]}.
|
|
64
|
+
|
|
65
|
+
If #{app_name.titleize} is for another agency, update the agency line in `app/views/layouts/application.html.erb`
|
|
66
|
+
|
|
67
|
+
EOM
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
3
5
|
module RailsTemplate18f
|
|
4
6
|
module Generators
|
|
5
7
|
class GithubActionsGenerator < ::Rails::Generators::Base
|
|
6
|
-
include
|
|
7
|
-
include
|
|
8
|
+
include Base
|
|
9
|
+
include PipelineOptions
|
|
8
10
|
|
|
9
11
|
class_option :node_version, desc: "Node version to test against in actions"
|
|
10
12
|
|
|
@@ -13,10 +15,6 @@ module RailsTemplate18f
|
|
|
13
15
|
Install Github Actions workflow files
|
|
14
16
|
DESC
|
|
15
17
|
|
|
16
|
-
def self.source_root
|
|
17
|
-
@source_root ||= File.expand_path("templates", __dir__)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
18
|
def install_actions
|
|
21
19
|
directory "github", ".github"
|
|
22
20
|
if !terraform?
|
|
@@ -26,10 +24,28 @@ module RailsTemplate18f
|
|
|
26
24
|
end
|
|
27
25
|
|
|
28
26
|
def update_readme
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
if file_content("README.md").match?(/^## CI\/CD$/)
|
|
28
|
+
insert_into_file "README.md", readme_cicd, after: "## CI/CD\n"
|
|
29
|
+
insert_into_file "README.md", readme_staging_deploy, after: "#### Staging\n"
|
|
30
|
+
insert_into_file "README.md", readme_prod_deploy, after: "#### Production\n"
|
|
31
|
+
insert_into_file "README.md", readme_credentials, after: "#### Credentials and other Secrets\n"
|
|
32
|
+
else
|
|
33
|
+
append_to_file "README.md", <<~EOM
|
|
34
|
+
## CI/CD
|
|
35
|
+
#{readme_cicd}
|
|
36
|
+
|
|
37
|
+
### Deployment
|
|
38
|
+
|
|
39
|
+
#### Staging
|
|
40
|
+
#{readme_staging_deploy}
|
|
41
|
+
|
|
42
|
+
#### Production
|
|
43
|
+
#{readme_prod_deploy}
|
|
44
|
+
|
|
45
|
+
#### Credentials and other Secrets
|
|
46
|
+
#{readme_credentials}
|
|
47
|
+
EOM
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
|
|
35
51
|
def update_boundary_diagram
|
|
@@ -48,7 +64,7 @@ EOB
|
|
|
48
64
|
readme_filename = "terraform/README.md"
|
|
49
65
|
insert_into_file readme_filename, " |- .force-action-apply\n", after: " |- secrets.auto.tfvars\n"
|
|
50
66
|
insert_into_file readme_filename, <<~EOM, after: /- `secrets.auto.tfvars`.*$/
|
|
51
|
-
- `.force-action-apply` is a file that can be updated to force GitHub Actions to run `terraform apply` during the deploy phase
|
|
67
|
+
\n- `.force-action-apply` is a file that can be updated to force GitHub Actions to run `terraform apply` during the deploy phase
|
|
52
68
|
EOM
|
|
53
69
|
end
|
|
54
70
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "bundler"
|
|
5
|
+
|
|
6
|
+
module RailsTemplate18f
|
|
7
|
+
module Generators
|
|
8
|
+
class I18nGenerator < ::Rails::Generators::Base
|
|
9
|
+
include Base
|
|
10
|
+
|
|
11
|
+
class_option :languages, default: "es,fr,zh", desc: "Comma separated list of supported language short codes"
|
|
12
|
+
|
|
13
|
+
desc <<~DESC
|
|
14
|
+
Description:
|
|
15
|
+
Install translation framework and configuration for given languages.
|
|
16
|
+
Always installs configuration for English
|
|
17
|
+
DESC
|
|
18
|
+
|
|
19
|
+
def install_helper_gem_and_tasks
|
|
20
|
+
return if file_content("Gemfile").match?(/gem "i18n-tasks"/)
|
|
21
|
+
gem_group :development, :test do
|
|
22
|
+
gem "i18n-tasks", "~> 0.9"
|
|
23
|
+
end
|
|
24
|
+
Bundler.with_original_env do
|
|
25
|
+
in_root do
|
|
26
|
+
run "bundle install"
|
|
27
|
+
run "cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/"
|
|
28
|
+
run "cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
insert_into_file "config/i18n-tasks.yml", "\n#{indent("- app/assets/builds", 4)}", after: "exclude:"
|
|
32
|
+
uncomment_lines "config/i18n-tasks.yml", "ignore_missing:"
|
|
33
|
+
insert_into_file "config/i18n-tasks.yml", indent(<<~EOM), after: "ignore_missing:\n"
|
|
34
|
+
- 'shared.languages.*'
|
|
35
|
+
- 'shared.header.{title,close,demo_banner,menu}'
|
|
36
|
+
EOM
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def install_translations
|
|
40
|
+
inside "config/locales" do
|
|
41
|
+
template "en.yml"
|
|
42
|
+
languages.each do |lang|
|
|
43
|
+
copy_file "#{lang}.yml"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def configure_i18n
|
|
49
|
+
application "config.i18n.fallbacks = [:en]"
|
|
50
|
+
available_regex = /^(\s*config.i18n.available_locales).*$/
|
|
51
|
+
if file_content("config/application.rb").match?(available_regex)
|
|
52
|
+
gsub_file "config/application.rb", available_regex, "\\1 = #{supported_languages}"
|
|
53
|
+
else
|
|
54
|
+
application "config.i18n.available_locales = #{supported_languages}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def install_nav_helper
|
|
59
|
+
inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper", indent(<<~'EOH')
|
|
60
|
+
def format_active_locale(locale_string)
|
|
61
|
+
link_classes = "usa-nav__link"
|
|
62
|
+
if locale_string.to_sym == I18n.locale
|
|
63
|
+
link_classes = "#{link_classes} usa-current"
|
|
64
|
+
end
|
|
65
|
+
link_to t("shared.languages.#{locale_string}"), root_path(locale: locale_string), class: link_classes
|
|
66
|
+
end
|
|
67
|
+
EOH
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def install_around_action
|
|
71
|
+
return if languages.empty?
|
|
72
|
+
inject_into_class "app/controllers/application_controller.rb", "ApplicationController", indent(<<~EOM)
|
|
73
|
+
around_action :switch_locale
|
|
74
|
+
|
|
75
|
+
def switch_locale(&action)
|
|
76
|
+
locale = params[:locale] || I18n.default_locale
|
|
77
|
+
I18n.with_locale(locale, &action)
|
|
78
|
+
end
|
|
79
|
+
EOM
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def install_route
|
|
83
|
+
return if languages.empty?
|
|
84
|
+
return if file_content("config/routes.rb").match?(/scope "\(:locale\)"/)
|
|
85
|
+
regex = /(^.+\.routes\.draw do\s*$)\n(.*)^end$/m
|
|
86
|
+
gsub_file "config/routes.rb", regex, <<~'EOR'
|
|
87
|
+
\1
|
|
88
|
+
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
|
|
89
|
+
# Your application routes go here
|
|
90
|
+
\2
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
EOR
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def supported_languages
|
|
99
|
+
@supported_languages ||= [:en, *languages]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def languages
|
|
103
|
+
@languages ||= options[:languages].split(",").map(&:to_sym)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -12,11 +12,11 @@ en:
|
|
|
12
12
|
secure_heading: Secure .gov websites use HTTPS
|
|
13
13
|
us_flag: U.S. Flag
|
|
14
14
|
header:
|
|
15
|
-
title: <%= app_name.titleize %>
|
|
16
|
-
menu: Menu
|
|
17
15
|
close: Close
|
|
18
|
-
primary: Primary navigation
|
|
19
16
|
demo_banner: TEST SITE - Do not use real personal information (demo purposes only) - TEST SITE
|
|
17
|
+
menu: Menu
|
|
18
|
+
primary: Primary navigation
|
|
19
|
+
title: <%= app_name.titleize %>
|
|
20
20
|
languages:
|
|
21
21
|
en: English
|
|
22
22
|
es: Español
|
|
@@ -12,8 +12,8 @@ es:
|
|
|
12
12
|
secure_heading: Los sitios web seguros .gov usan HTTPS
|
|
13
13
|
us_flag: Bandera de Estados Unidos
|
|
14
14
|
header:
|
|
15
|
-
menu: Menú
|
|
16
15
|
close: Cerrar
|
|
17
|
-
primary: Navegacion primaria
|
|
18
16
|
demo_banner: SITIO DE PRUEBA - No utilice información personal real (sólo para propósitos de demostración) - SITIO DE PRUEBA
|
|
19
|
-
|
|
17
|
+
menu: Menú
|
|
18
|
+
primary: Navegacion primaria
|
|
19
|
+
skip_link: Salte al contenido principal
|
|
@@ -8,15 +8,12 @@ fr:
|
|
|
8
8
|
lock: Verrou
|
|
9
9
|
locked_padlock: Verrou fermé
|
|
10
10
|
official_site: Un site web officiel du gouvernement des États-Unis
|
|
11
|
-
secure_description_html: Un <strong>verrou</strong> (%{lock_icon}) ou
|
|
12
|
-
<strong>https://</strong> signifie que vous êtes connecté en toute
|
|
13
|
-
sécurité au site Web .gov. Partagez des informations sensibles
|
|
14
|
-
uniquement sur des sites Web officiels et sécurisés.
|
|
11
|
+
secure_description_html: Un <strong>verrou</strong> (%{lock_icon}) ou <strong>https://</strong> signifie que vous êtes connecté en toute sécurité au site Web .gov. Partagez des informations sensibles uniquement sur des sites Web officiels et sécurisés.
|
|
15
12
|
secure_heading: Les sites Web sécurisés .gov utilisent HTTPS
|
|
16
13
|
us_flag: Drapeau américain
|
|
17
14
|
header:
|
|
18
|
-
menu: Menu
|
|
19
15
|
close: Fermer
|
|
20
|
-
primary: Navigation primaire
|
|
21
16
|
demo_banner: SITE DE TEST - N’utilisez pas de véritables données personnelles (il s’agit d’une démonstration seulement) - SITE DE TEST
|
|
17
|
+
menu: Menu
|
|
18
|
+
primary: Navigation primaire
|
|
22
19
|
skip_link: Passer au contenu principal
|
|
File without changes
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "bundler"
|
|
5
|
+
|
|
6
|
+
module RailsTemplate18f
|
|
7
|
+
module Generators
|
|
8
|
+
class I18nJsGenerator < ::Rails::Generators::Base
|
|
9
|
+
include Base
|
|
10
|
+
|
|
11
|
+
desc <<~DESC
|
|
12
|
+
Description:
|
|
13
|
+
Install and configure i18n-js gem to provide translations to JS code.
|
|
14
|
+
|
|
15
|
+
By default, will only export translations with keys that match `*.js.*`
|
|
16
|
+
DESC
|
|
17
|
+
|
|
18
|
+
def install_gem_and_tasks
|
|
19
|
+
return if file_content("Gemfile").match?(/gem "i18n-js"/)
|
|
20
|
+
gem "i18n-js", "~> 3.9"
|
|
21
|
+
Bundler.with_original_env do
|
|
22
|
+
in_root do
|
|
23
|
+
run "bundle install"
|
|
24
|
+
run "yarn add i18n-js"
|
|
25
|
+
generate "i18n:js:config"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
append_to_file "config/i18n-js.yml", <<~EOYAML
|
|
29
|
+
# remove `only` to include all translations
|
|
30
|
+
translations:
|
|
31
|
+
- file: "app/assets/builds/translations.js"
|
|
32
|
+
only: "*.js.*"
|
|
33
|
+
EOYAML
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def configure_asset_pipeline
|
|
37
|
+
copy_file "lib/tasks/i18n.rake"
|
|
38
|
+
environment "config.middleware.use I18n::JS::Middleware", env: :development
|
|
39
|
+
insert_into_file "app/views/layouts/application.html.erb", indent(<<~EOHTML, 4), after: /<%= stylesheet_link_tag "application".*$\n/
|
|
40
|
+
<%= javascript_include_tag "i18n", "data-turbo-track": "reload" %>
|
|
41
|
+
<%= javascript_include_tag "translations", "data-turbo-track": "reload" %>
|
|
42
|
+
EOHTML
|
|
43
|
+
append_to_file "app/assets/config/manifest.js", <<~EOJS
|
|
44
|
+
//= link i18n.js
|
|
45
|
+
//= link translations.js
|
|
46
|
+
EOJS
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ignore_generated_file
|
|
50
|
+
unless skip_git?
|
|
51
|
+
append_to_file ".gitignore", <<~EOM
|
|
52
|
+
|
|
53
|
+
# Generated by i18n-js
|
|
54
|
+
/public/javascripts/i18n.js
|
|
55
|
+
EOM
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
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"])
|
|
9
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module RailsTemplate18f
|
|
6
|
+
module Generators
|
|
7
|
+
class NewrelicGenerator < ::Rails::Generators::Base
|
|
8
|
+
include Base
|
|
9
|
+
|
|
10
|
+
desc <<~DESC
|
|
11
|
+
Description:
|
|
12
|
+
Install NewRelic config for FedRAMP collection
|
|
13
|
+
DESC
|
|
14
|
+
|
|
15
|
+
def update_content_security_policy
|
|
16
|
+
csp_file = "config/initializers/content_security_policy.rb"
|
|
17
|
+
gsub_file csp_file, /(policy.script_src .*)$/, '\1, "https://js-agent.newrelic.com", "https://*.nr-data.net"'
|
|
18
|
+
if file_content(csp_file).match?(/policy.connect_src/)
|
|
19
|
+
gsub_file csp_file, /(policy.connect_src .*)$/, '\1, "https://*.nr-data.net"'
|
|
20
|
+
else
|
|
21
|
+
gsub_file csp_file, /((#?)(\s+)policy.script_src .*)$/, "\\1\n\\2\\3policy.connect_src :self, \"https://*.nr-data.net\""
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def install_gem
|
|
26
|
+
gem "newrelic_rpm", "~> 8.4"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def install_config
|
|
30
|
+
template "config/newrelic.yml"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update_cloud_gov_manifest
|
|
34
|
+
insert_into_file "manifest.yml", " NEW_RELIC_LOG: stdout\n", before: /^\s+processes:/
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def update_readme
|
|
38
|
+
insertion_regex = /^## Documentation$/
|
|
39
|
+
if file_content("README.md").match?(insertion_regex)
|
|
40
|
+
insert_into_file "README.md", readme, before: insertion_regex
|
|
41
|
+
else
|
|
42
|
+
append_to_file "README.md", readme
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def update_boundary_diagram
|
|
47
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
|
48
|
+
insert_into_file boundary_filename, <<EOB, after: "Boundary(gsa_saas, \"GSA-authorized SaaS\") {\n"
|
|
49
|
+
System_Ext(newrelic, "New Relic", "Monitoring SaaS")
|
|
50
|
+
EOB
|
|
51
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
|
52
|
+
Rel(app, newrelic, "reports telemetry (ruby agent)", "tcp (443)")
|
|
53
|
+
Rel(browser, newrelic, "reports ux metrics (javascript agent)", "https (443)")
|
|
54
|
+
Rel(developer, newrelic, "Manage performance", "https (443)")
|
|
55
|
+
EOB
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
no_tasks do
|
|
59
|
+
def readme
|
|
60
|
+
<<~EOM
|
|
61
|
+
## Monitoring with New Relic
|
|
62
|
+
|
|
63
|
+
The [New Relic Ruby agent](https://docs.newrelic.com/docs/apm/agents/ruby-agent/getting-started/introduction-new-relic-ruby) has been installed for monitoring this application.
|
|
64
|
+
|
|
65
|
+
The config lives at `config/newrelic.yml`, and points to a [FEDRAMP version of the New Relic service as its host](https://docs.newrelic.com/docs/security/security-privacy/compliance/fedramp-compliant-endpoints/). To access the metrics dashboard, you will need to be connected to VPN.
|
|
66
|
+
|
|
67
|
+
### Getting started
|
|
68
|
+
|
|
69
|
+
To get started sending metrics via New Relic APM:
|
|
70
|
+
1. Add your New Relic license key to the Rails credentials with key `new_relic_key`.
|
|
71
|
+
1. Optionally, update `app_name` entries in `config/newrelic.yml` with what is registered for your application in New Relic
|
|
72
|
+
1. Comment out the `agent_enabled: false` line in `config/newrelic.yml`
|
|
73
|
+
1. Add the [Javascript snippet provided by New Relic](https://docs.newrelic.com/docs/browser/browser-monitoring/installation/install-browser-monitoring-agent) into `application.html.erb`. It is recommended to vary this based on environment (i.e. include one snippet for staging and another for production).
|
|
74
|
+
EOM
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
common: &default_settings
|
|
12
12
|
# Required license key associated with your New Relic account.
|
|
13
|
-
license_key:
|
|
13
|
+
license_key: <%%= Rails.application.credentials.new_relic_key %>
|
|
14
14
|
# FEDRAMP-specific New Relic host
|
|
15
15
|
# https://docs.newrelic.com/docs/security/security-privacy/compliance/fedramp-compliant-endpoints/
|
|
16
16
|
host: 'gov-collector.newrelic.com'
|
|
17
17
|
|
|
18
18
|
# Your application name. Renaming here affects where data displays in New
|
|
19
19
|
# Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications
|
|
20
|
-
app_name:
|
|
20
|
+
app_name: <%= app_name.titleize %>
|
|
21
21
|
|
|
22
22
|
monitor_mode: true
|
|
23
23
|
|
|
@@ -30,8 +30,8 @@ common: &default_settings
|
|
|
30
30
|
|
|
31
31
|
# This line disables agent regardless of other settings.
|
|
32
32
|
# To enable the New Relic agent:
|
|
33
|
-
# 1)
|
|
34
|
-
# 2)
|
|
33
|
+
# 1) add the New Relic license keys to the appropriate encrypted credentials file(s)
|
|
34
|
+
# 2) Optionally, update app_name entries in this file with the application name you want to show in New Relic
|
|
35
35
|
# 3) Comment out the line below
|
|
36
36
|
agent_enabled: false
|
|
37
37
|
|
|
@@ -44,7 +44,7 @@ common: &default_settings
|
|
|
44
44
|
# If your application has other named environments, configure them here.
|
|
45
45
|
development:
|
|
46
46
|
<<: *default_settings
|
|
47
|
-
app_name:
|
|
47
|
+
app_name: <%= app_name.titleize %> (Development)
|
|
48
48
|
|
|
49
49
|
test:
|
|
50
50
|
<<: *default_settings
|
|
@@ -58,8 +58,8 @@ ci:
|
|
|
58
58
|
|
|
59
59
|
staging:
|
|
60
60
|
<<: *default_settings
|
|
61
|
-
app_name:
|
|
61
|
+
app_name: <%= app_name.titleize %> (Staging)
|
|
62
62
|
|
|
63
63
|
production:
|
|
64
64
|
<<: *default_settings
|
|
65
|
-
app_name:
|
|
65
|
+
app_name: <%= app_name.titleize %> (Production)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module RailsTemplate18f
|
|
6
|
+
module Generators
|
|
7
|
+
class SidekiqGenerator < ::Rails::Generators::Base
|
|
8
|
+
include Base
|
|
9
|
+
|
|
10
|
+
desc <<~DESC
|
|
11
|
+
Description:
|
|
12
|
+
Install Sidekiq and configure it as the ActiveJob backend
|
|
13
|
+
DESC
|
|
14
|
+
|
|
15
|
+
def install_gem
|
|
16
|
+
gem "sidekiq", "~> 6.4"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def configure_server_runner
|
|
20
|
+
append_to_file "Procfile.dev", "worker: bundle exec sidekiq\n"
|
|
21
|
+
insert_into_file "manifest.yml", indent(<<~EOYAML), after: /processes:$\n/
|
|
22
|
+
- type: worker
|
|
23
|
+
instances: ((worker_instances))
|
|
24
|
+
memory: ((worker_memory))
|
|
25
|
+
command: bundle exec sidekiq
|
|
26
|
+
EOYAML
|
|
27
|
+
insert_into_file "manifest.yml", "\n - #{app_name}-redis-((env))", after: "services:"
|
|
28
|
+
inside "config/deployment" do
|
|
29
|
+
append_to_file "staging.yml", <<~EOYAML
|
|
30
|
+
worker_instances: 1
|
|
31
|
+
worker_memory: 256M
|
|
32
|
+
EOYAML
|
|
33
|
+
append_to_file "production.yml", <<~EOYAML
|
|
34
|
+
worker_instances: 1
|
|
35
|
+
worker_memory: 512M
|
|
36
|
+
EOYAML
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def configure_active_job
|
|
41
|
+
generate "rails_template18f:cloud_gov_config"
|
|
42
|
+
copy_file "config/initializers/redis.rb"
|
|
43
|
+
application "config.active_job.queue_adapter = :sidekiq"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def configure_sidekiq_ui
|
|
47
|
+
prepend_to_file "config/routes.rb", "require \"sidekiq/web\"\n\n"
|
|
48
|
+
route <<~EOR
|
|
49
|
+
if Rails.env.development?
|
|
50
|
+
mount Sidekiq::Web => "/sidekiq"
|
|
51
|
+
end
|
|
52
|
+
EOR
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def update_boundary_diagram
|
|
56
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
|
57
|
+
|
|
58
|
+
insert_into_file boundary_filename, indent(<<~EOB, 16), after: /ContainerDb\(app_db.*$\n/
|
|
59
|
+
Container(worker, "<&layers> Sidekiq workers", "Ruby #{ruby_version}, Sidekiq", "Perform background work and data processing")
|
|
60
|
+
ContainerDb(redis, "Redis Database", "AWS ElastiCache (Redis)", "Background job queue")
|
|
61
|
+
EOB
|
|
62
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
|
63
|
+
Rel(app, redis, "enqueue job parameters", "redis")
|
|
64
|
+
Rel(worker, redis, "dequeues job parameters", "redis")
|
|
65
|
+
Rel(worker, app_db, "reads/writes primary data", "psql (5432)")
|
|
66
|
+
EOB
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Rails.application.config.to_prepare do
|
|
4
|
+
redis_url = CloudGovConfig.dig "aws-elasticache-redis", "credentials", "uri"
|
|
5
|
+
if redis_url.present?
|
|
6
|
+
Sidekiq.configure_server do |config|
|
|
7
|
+
config.redis = {url: redis_url, ssl: true}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Sidekiq.configure_client do |config|
|
|
11
|
+
config.redis = {url: redis_url, ssl: true}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/{templates → lib/generators/rails_template18f/terraform/templates}/terraform/README.md.tt
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -9,9 +9,9 @@ module "s3" {
|
|
|
9
9
|
cf_api_url = local.cf_api_url
|
|
10
10
|
cf_user = var.cf_user
|
|
11
11
|
cf_password = var.cf_password
|
|
12
|
-
cf_org_name = "<%=
|
|
13
|
-
cf_space_name = "<%=
|
|
14
|
-
s3_service_name = local.s3_service_name<% if
|
|
12
|
+
cf_org_name = "<%= cloud_gov_organization %>"
|
|
13
|
+
cf_space_name = "<%= cloud_gov_production_space %>"
|
|
14
|
+
s3_service_name = local.s3_service_name<% if cloud_gov_organization == "sandbox-gsa" %>
|
|
15
15
|
s3_plan_name = "basic-sandbox"<% end %>
|
|
16
16
|
}
|
|
17
17
|
|
|
File without changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
3
|
if [[ ! -f "secrets.auto.tfvars" ]]; then
|
|
4
|
-
../create_space_deployer.sh <%=
|
|
4
|
+
../create_space_deployer.sh <%= cloud_gov_production_space %> config-bootstrap-deployer > secrets.auto.tfvars
|
|
5
5
|
fi
|
|
6
6
|
|
|
7
7
|
if [[ $# -gt 0 ]]; then
|
|
File without changes
|