rails_template_18f 2.0.0 → 2.2.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 +13 -0
- data/Gemfile.lock +9 -7
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +4 -3
- data/lib/generators/rails_template18f/auditree/auditree_generator.rb +36 -6
- data/lib/generators/rails_template18f/auditree/templates/gitlab/auditree.yml.tt +48 -0
- data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +12 -2
- data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +0 -8
- data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +6 -7
- data/lib/generators/rails_template18f/cloud_gov_config/templates/spec/models/cloud_gov_config_spec.rb +13 -19
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +0 -4
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +3 -1
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +3 -1
- data/lib/generators/rails_template18f/gitlab_ci/gitlab_ci_generator.rb +138 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/node.yml.tt +11 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/rails.yml +75 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/ruby.yml +7 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab/terraform.yml +33 -0
- data/lib/generators/rails_template18f/gitlab_ci/templates/gitlab-ci.yml.tt +213 -0
- data/lib/generators/rails_template18f/oscal/oscal_generator.rb +15 -1
- data/lib/generators/rails_template18f/oscal/templates/bin/trestle.tt +10 -1
- data/lib/generators/rails_template18f/oscal/templates/gitlab/trestle.yml.tt +29 -0
- data/lib/generators/rails_template18f/public_egress/public_egress_generator.rb +16 -32
- data/lib/generators/rails_template18f/sidekiq/templates/config/initializers/redis.rb +1 -1
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/apply.sh +25 -0
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/main.tf.tt +98 -0
- data/lib/generators/rails_template18f/terraform/templates/gitlab_bootstrap/setup_shadowenv.sh +59 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/templates/backend_config.tftpl +6 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/templates/bot_secrets.tftpl +5 -0
- data/lib/generators/rails_template18f/terraform/templates/s3_bootstrap/common/users.auto.tfvars +5 -0
- data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/main.tf.tt +4 -11
- data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/main.tf.tt +3 -3
- data/lib/generators/rails_template18f/terraform/templates/terraform/.shadowenv.d/.gitignore +3 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +38 -36
- data/lib/generators/rails_template18f/terraform/templates/terraform/app.tf.tt +1 -6
- data/lib/generators/rails_template18f/terraform/templates/terraform/main.tf.tt +30 -19
- data/lib/generators/rails_template18f/terraform/templates/terraform/production.tfvars.tt +3 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/providers.tf.tt +4 -24
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging.tfvars.tt +5 -5
- data/lib/generators/rails_template18f/terraform/templates/terraform/terraform.sh.tt +40 -55
- data/lib/generators/rails_template18f/terraform/templates/terraform/variables.tf.tt +11 -12
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +78 -6
- data/lib/rails_template18f/version.rb +1 -1
- data/template.rb +50 -25
- data/templates/{pa11yci.js → pa11yci.js.tt} +5 -0
- metadata +28 -20
- data/lib/generators/rails_template18f/terraform/templates/terraform/bootstrap/templates/backend_config.tftpl +0 -8
- data/lib/generators/rails_template18f/terraform/templates/terraform/sandbox_bot/main.tf +0 -74
- data/lib/generators/rails_template18f/terraform/templates/terraform/sandbox_bot/run.sh +0 -17
- /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/assemble-ssp.yml.tt +0 -0
- /data/lib/generators/rails_template18f/{github_actions → oscal}/templates/github/workflows/validate-ssp.yml +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap/templates → gitlab_bootstrap}/bot_secrets.tftpl +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → gitlab_bootstrap}/users.auto.tfvars +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{terraform/bootstrap → s3_bootstrap/common}/apply.sh +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{full_bootstrap → s3_bootstrap/full}/imports.tf.tftpl +0 -0
- /data/lib/generators/rails_template18f/terraform/templates/{sandbox_bootstrap → s3_bootstrap/sandbox}/imports.tf.tftpl +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bab13c0d757c29b86c139635bed3f016cc486d38299b7aa90533d888b6995d69
|
4
|
+
data.tar.gz: 447e73554b32dd86782cf52c4cda2699f55c4e0706c05f813e82515a2e61912f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cad79214c9110e3fb33968b8c6d1fc98477c6c979bc58724e9b88f57985456ca7d404515dd004891dade32d4e95183f1a90c12d4d05ee87753f52867f9efde94
|
7
|
+
data.tar.gz: ecb278387c12d47fc9bc611f26c0787fa7c4c2dda43fa14ce8f176bfb4cf9d0d2c6b04718ab0faa3569b4f5897e9d65cdc0b0944972c64648e8e401d9b341881
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [2.2.0] - 2025-06-27
|
4
|
+
|
5
|
+
- Prevent non-compliant hostnames by replacing underscores with dashes
|
6
|
+
- use shadowenv for configuring terraform backend secrets
|
7
|
+
- use GitLab http backend for terraform state storage whenever configuring both terraform and GitLab CI
|
8
|
+
- Create GitLabCI jobs for oscal and auditree generators
|
9
|
+
- fixes for deploying to the sandbox-gsa cloug.gov org
|
10
|
+
|
11
|
+
## [2.1.0] - 2025-04-29
|
12
|
+
|
13
|
+
- Terraform generator updates to remove the old cloudfoundy-community provider and reduce the need for cloud.gov service accounts
|
14
|
+
- New GitLab CI generator for use with DevTools GitLab
|
15
|
+
|
3
16
|
## [2.0.0] - 2025-01-16
|
4
17
|
|
5
18
|
- Default new apps to Rails 8, including support for thruster proxy
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rails_template_18f (2.
|
4
|
+
rails_template_18f (2.2.0)
|
5
5
|
activesupport (~> 8.0.1)
|
6
6
|
colorize (~> 1.1)
|
7
7
|
railties (~> 8.0.1)
|
@@ -71,11 +71,11 @@ GEM
|
|
71
71
|
crass (~> 1.0.2)
|
72
72
|
nokogiri (>= 1.12.0)
|
73
73
|
minitest (5.25.4)
|
74
|
-
nokogiri (1.18.
|
74
|
+
nokogiri (1.18.8-arm64-darwin)
|
75
75
|
racc (~> 1.4)
|
76
|
-
nokogiri (1.18.
|
76
|
+
nokogiri (1.18.8-x86_64-darwin)
|
77
77
|
racc (~> 1.4)
|
78
|
-
nokogiri (1.18.
|
78
|
+
nokogiri (1.18.8-x86_64-linux-gnu)
|
79
79
|
racc (~> 1.4)
|
80
80
|
parallel (1.26.3)
|
81
81
|
parser (3.3.6.0)
|
@@ -85,8 +85,9 @@ GEM
|
|
85
85
|
date
|
86
86
|
stringio
|
87
87
|
racc (1.8.1)
|
88
|
-
rack (3.1.
|
89
|
-
rack-session (2.
|
88
|
+
rack (3.1.16)
|
89
|
+
rack-session (2.1.1)
|
90
|
+
base64 (>= 0.1.0)
|
90
91
|
rack (>= 3.0.0)
|
91
92
|
rack-test (2.2.0)
|
92
93
|
rack (>= 1.3)
|
@@ -171,12 +172,13 @@ GEM
|
|
171
172
|
unicode-display_width (3.1.3)
|
172
173
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
173
174
|
unicode-emoji (4.0.4)
|
174
|
-
uri (1.0.
|
175
|
+
uri (1.0.3)
|
175
176
|
useragent (0.16.11)
|
176
177
|
zeitwerk (2.7.1)
|
177
178
|
|
178
179
|
PLATFORMS
|
179
180
|
arm64-darwin-23
|
181
|
+
arm64-darwin-24
|
180
182
|
x86_64-darwin-20
|
181
183
|
x86_64-darwin-21
|
182
184
|
x86_64-linux
|
@@ -20,12 +20,13 @@ module RailsTemplate18f
|
|
20
20
|
environment "config.active_storage.service = :local", env: "ci"
|
21
21
|
append_to_file "config/storage.yml", <<~EOYAML
|
22
22
|
|
23
|
+
<% cgc = CloudGovConfig.new %>
|
23
24
|
amazon:
|
24
25
|
service: S3
|
25
|
-
access_key_id: <%=
|
26
|
-
secret_access_key: <%=
|
26
|
+
access_key_id: <%= cgc.dig(:s3, :credentials, :access_key_id) %>
|
27
|
+
secret_access_key: <%= cgc.dig(:s3, :credentials, :secret_access_key) %>
|
27
28
|
region: us-gov-west-1
|
28
|
-
bucket: <%=
|
29
|
+
bucket: <%= cgc.dig(:s3, :credentials, :bucket) %>
|
29
30
|
EOYAML
|
30
31
|
end
|
31
32
|
|
@@ -41,7 +41,7 @@ module RailsTemplate18f
|
|
41
41
|
plant-helper -f /tmp/rspec.json -c assessment-plans -d "RSpec run assessment plan"
|
42
42
|
-t 31536000 -l #{auditree_evidence_locker}
|
43
43
|
|
44
|
-
- name:
|
44
|
+
- name: Plant assessment results in evidence locker
|
45
45
|
uses: ./.github/actions/auditree-cmd
|
46
46
|
env:
|
47
47
|
GITHUB_TOKEN: ${{ secrets.AUDITREE_GITHUB_TOKEN }}
|
@@ -54,6 +54,19 @@ PLANT_HELPER_STEPS
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
def copy_gitlab_actions
|
58
|
+
if file_exists? ".gitlab-ci.yml"
|
59
|
+
directory "gitlab", ".gitlab"
|
60
|
+
insert_into_file ".gitlab-ci.yml", " - local: \".gitlab/auditree.yml\"\n", after: /^include:\n/
|
61
|
+
insert_into_file ".gitlab-ci.yml", " AUDITREE_VERSION: #{docker_auditree_tag}\n", after: /^variables:\n/
|
62
|
+
insert_into_file ".gitlab-ci.yml", <<EOY, after: /^\s+- bundle exec rspec\n/
|
63
|
+
artifacts:
|
64
|
+
paths:
|
65
|
+
- tmp/oscal/**/*
|
66
|
+
EOY
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
57
70
|
def update_readme
|
58
71
|
if file_content("README.md").match?("## Documentation")
|
59
72
|
insert_into_file "README.md", readme_contents, after: "## Documentation\n"
|
@@ -74,7 +87,7 @@ PLANT_HELPER_STEPS
|
|
74
87
|
end
|
75
88
|
|
76
89
|
def auditree_evidence_locker
|
77
|
-
options[:evidence_locker].present? ? options[:evidence_locker] : "
|
90
|
+
options[:evidence_locker].present? ? options[:evidence_locker] : "REPLACE_THIS_WITH_YOUR_EVIDENCE_LOCKER_REPO"
|
78
91
|
end
|
79
92
|
|
80
93
|
def git_email
|
@@ -98,10 +111,9 @@ PLANT_HELPER_STEPS
|
|
98
111
|
1. Docker desktop must be running
|
99
112
|
1. Initialize the config file with `bin/auditree init`
|
100
113
|
1. Create an evidence locker repository with a default or blank README
|
101
|
-
1.
|
102
|
-
|
103
|
-
|
104
|
-
1. Copy the `devtools_cloud_gov` component definition into the project with the latest docker-trestle
|
114
|
+
1. Update `config/auditree.template.json` with the repo address for your locker
|
115
|
+
#{ci_readme_contents.chomp}
|
116
|
+
1. Copy the `devtools_cloud_gov` component definition into the project with the latest docker-trestle after [setting up docker-trestle](#initial-trestle-setup)
|
105
117
|
|
106
118
|
#### Ongoing use
|
107
119
|
|
@@ -109,6 +121,24 @@ PLANT_HELPER_STEPS
|
|
109
121
|
auditree and using new checks.
|
110
122
|
README
|
111
123
|
end
|
124
|
+
|
125
|
+
def ci_readme_contents
|
126
|
+
if file_exists? ".gitlab-ci.yml"
|
127
|
+
<<~README
|
128
|
+
1. Remove the `repo_integrity` section of `config/auditree.template.json`
|
129
|
+
1. Create a gitlab personal access token with `write_repository` scope to interact with the code repo and evidence locker and set as `AUDITREE_GITLAB_TOKEN` secret within your CI/CD variables.
|
130
|
+
#{options[:evidence_locker].blank? ? "1. Update `.gitlab/auditree.yml` with the locker repository URL" : ""}
|
131
|
+
README
|
132
|
+
elsif file_exists? ".github/workflows"
|
133
|
+
<<~README
|
134
|
+
1. Update `config/auditree.template.json` with the repo address for your code repos
|
135
|
+
1. Create a github personal access token to interact with the code repo and evidence locker and set as `AUDITREE_GITHUB_TOKEN` secret within your Github Actions secrets.
|
136
|
+
#{options[:evidence_locker].blank? ? "1. Update `.github/workflows/rspec.yml` with the locker repository URL" : ""}
|
137
|
+
README
|
138
|
+
else
|
139
|
+
""
|
140
|
+
end
|
141
|
+
end
|
112
142
|
end
|
113
143
|
end
|
114
144
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
.auditree:setup:
|
2
|
+
inherit:
|
3
|
+
default: false
|
4
|
+
image: "ghcr.io/gsa-tts/auditree:${AUDITREE_VERSION}"
|
5
|
+
variables:
|
6
|
+
CDEF: "${CI_PROJECT_DIR}/doc/compliance/oscal/component-definitions/devtools_cloud_gov/component-definition.json"
|
7
|
+
AUDITREE_CONFIG: "${CI_PROJECT_DIR}/config/auditree.template.json"
|
8
|
+
before_script:
|
9
|
+
- git config --global user.name "$GITLAB_USER_NAME"
|
10
|
+
- git config --global user.email "$GITLAB_USER_EMAIL"
|
11
|
+
- cf api api.fr.cloud.gov
|
12
|
+
- cd $HOME
|
13
|
+
- export GITLAB_TOKEN="auditree-gitlab-token:${AUDITREE_GITLAB_TOKEN}"
|
14
|
+
|
15
|
+
auditree:
|
16
|
+
extends: .auditree:setup
|
17
|
+
stage: scan
|
18
|
+
script:
|
19
|
+
- fetch -c "$CDEF" -t "$AUDITREE_CONFIG"
|
20
|
+
- check -c "$CDEF" -t "$AUDITREE_CONFIG" -o "$CI_PROJECT_DIR"
|
21
|
+
artifacts:
|
22
|
+
paths:
|
23
|
+
- auditree.json
|
24
|
+
rules:
|
25
|
+
- if: $CI_PIPELINE_SOURCE == "schedule"
|
26
|
+
|
27
|
+
rspec:plant:
|
28
|
+
extends: .auditree:setup
|
29
|
+
stage: test
|
30
|
+
needs: ["rspec"]
|
31
|
+
variables:
|
32
|
+
PLAN_FILE: "${CI_PROJECT_DIR}/tmp/oscal/assessment-plans/rspec/assessment-plan.json"
|
33
|
+
RESULT_FILE: "${CI_PROJECT_DIR}/tmp/oscal/assessment-results/rspec/assessment-results.json"
|
34
|
+
script:
|
35
|
+
- |
|
36
|
+
if [ -f "$PLAN_FILE" ]; then
|
37
|
+
plant-helper -f "$PLAN_FILE" -c assessment-plans -d "RSpec run assessment plan" -t 31536000 -l "<%= auditree_evidence_locker %>"
|
38
|
+
else
|
39
|
+
echo "No plan file, skipping plant"
|
40
|
+
fi
|
41
|
+
- |
|
42
|
+
if [ -f "$RESULT_FILE" ]; then
|
43
|
+
plant-helper -f "$RESULT_FILE" -c assessment-results -d "RSpec run assessment results" -t 31536000 -l "<%= auditree_evidence_locker %>"
|
44
|
+
else
|
45
|
+
echo "No result file, skipping plant"
|
46
|
+
fi
|
47
|
+
rules:
|
48
|
+
- if: $CI_PIPELINE_SOURCE != "schedule"
|
@@ -314,13 +314,15 @@ jobs:
|
|
314
314
|
- attach_workspace:
|
315
315
|
at: .
|
316
316
|
- terraform/plan:
|
317
|
+
environment:
|
318
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
319
|
+
CF_USER: "$CF_USERNAME"
|
317
320
|
path: terraform
|
318
321
|
out: staging.out
|
319
322
|
var_file: staging.tfvars
|
320
323
|
var: >-
|
321
324
|
rails_master_key="$RAILS_MASTER_KEY",
|
322
325
|
cf_user="$CF_USERNAME",
|
323
|
-
cf_password="$CF_PASSWORD"
|
324
326
|
- persist_to_workspace:
|
325
327
|
root: .
|
326
328
|
paths:
|
@@ -332,6 +334,9 @@ jobs:
|
|
332
334
|
- attach_workspace:
|
333
335
|
at: .
|
334
336
|
- terraform/apply:
|
337
|
+
environment:
|
338
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
339
|
+
CF_USER: "$CF_USERNAME"
|
335
340
|
path: terraform
|
336
341
|
plan: staging.out<% if terraform_manage_spaces? %>
|
337
342
|
|
@@ -358,13 +363,15 @@ jobs:
|
|
358
363
|
- attach_workspace:
|
359
364
|
at: .
|
360
365
|
- terraform/plan:
|
366
|
+
environment:
|
367
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
368
|
+
CF_USER: "$CF_USERNAME"
|
361
369
|
path: terraform
|
362
370
|
out: production.out
|
363
371
|
var_file: production.tfvars
|
364
372
|
var: >-
|
365
373
|
rails_master_key="$PRODUCTION_RAILS_MASTER_KEY",
|
366
374
|
cf_user="$CF_USERNAME",
|
367
|
-
cf_password="$CF_PASSWORD"
|
368
375
|
- persist_to_workspace:
|
369
376
|
root: .
|
370
377
|
paths:
|
@@ -376,6 +383,9 @@ jobs:
|
|
376
383
|
- attach_workspace:
|
377
384
|
at: .
|
378
385
|
- terraform/apply:
|
386
|
+
environment:
|
387
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
388
|
+
CF_USER: "$CF_USERNAME"
|
379
389
|
path: terraform
|
380
390
|
plan: production.out<% end %>
|
381
391
|
|
@@ -12,14 +12,6 @@ module RailsTemplate18f
|
|
12
12
|
Install a helper class to retrieve configuration from ENV["VCAP_SERVICES"]
|
13
13
|
DESC
|
14
14
|
|
15
|
-
def install_climate_control
|
16
|
-
return if gem_installed?("climate_control")
|
17
|
-
gem_group :test do
|
18
|
-
gem "climate_control", "~> 1.2"
|
19
|
-
end
|
20
|
-
bundle_install
|
21
|
-
end
|
22
|
-
|
23
15
|
def install_model_and_test
|
24
16
|
copy_file "app/models/cloud_gov_config.rb"
|
25
17
|
copy_file "spec/models/cloud_gov_config_spec.rb"
|
data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class CloudGovConfig
|
4
|
-
|
4
|
+
attr_reader :vcap_services
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
first, *rest = path
|
9
|
-
vcap_services[first]&.first&.dig(*rest)
|
6
|
+
def initialize(env = ENV["VCAP_SERVICES"])
|
7
|
+
@vcap_services = env.blank? ? {} : JSON.parse(env).with_indifferent_access
|
10
8
|
end
|
11
9
|
|
12
|
-
def
|
13
|
-
|
10
|
+
def dig(*path)
|
11
|
+
first, *rest = path
|
12
|
+
vcap_services[first]&.first&.dig(*rest)
|
14
13
|
end
|
15
14
|
end
|
@@ -3,35 +3,29 @@
|
|
3
3
|
require "rails_helper"
|
4
4
|
|
5
5
|
RSpec.describe CloudGovConfig, type: :model do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
describe "#dig" do
|
7
|
+
[nil, "", "{}"].each do |blank|
|
8
|
+
context "VCAP_SERVICES is #{blank.inspect}" do
|
9
|
+
subject { described_class.new blank }
|
10
|
+
it "returns nil" do
|
11
|
+
expect(subject.dig(:s3, :credentials, :bucket)).to be_nil
|
12
|
+
end
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
context "VCAP_SERVICES is set" do
|
17
|
+
subject { described_class.new vcap }
|
16
18
|
let(:bucket_name) { "bucket-name" }
|
17
19
|
let(:vcap) {
|
18
20
|
{
|
19
|
-
s3: [
|
20
|
-
{
|
21
|
-
|
22
|
-
bucket: bucket_name
|
23
|
-
}
|
21
|
+
s3: [{
|
22
|
+
credentials: {
|
23
|
+
bucket: bucket_name
|
24
24
|
}
|
25
|
-
]
|
26
|
-
}
|
25
|
+
}]
|
26
|
+
}.to_json
|
27
27
|
}
|
28
28
|
|
29
|
-
around do |example|
|
30
|
-
ClimateControl.modify VCAP_SERVICES: vcap.to_json do
|
31
|
-
example.run
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
29
|
it "can find a path" do
|
36
30
|
expect(subject.dig(:s3, :credentials, :bucket)).to eq bucket_name
|
37
31
|
end
|
@@ -17,10 +17,6 @@ module RailsTemplate18f
|
|
17
17
|
|
18
18
|
def install_actions
|
19
19
|
directory "github", ".github"
|
20
|
-
if !oscal_dir_exists?
|
21
|
-
remove_file ".github/workflows/validate-ssp.yml"
|
22
|
-
remove_file ".github/workflows/assemble-ssp.yml"
|
23
|
-
end
|
24
20
|
if !terraform_manage_spaces?
|
25
21
|
remove_file ".github/workflows/terraform-production.yml"
|
26
22
|
remove_file ".github/workflows/deploy-production.yml"
|
@@ -47,8 +47,10 @@ jobs:
|
|
47
47
|
- name: Terraform apply
|
48
48
|
uses: dflook/terraform-apply@v1
|
49
49
|
env:
|
50
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
51
|
+
CF_USER: ${{ secrets.CF_USERNAME }}
|
52
|
+
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
|
50
53
|
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
51
|
-
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
52
54
|
TF_VAR_rails_master_key: ${{ secrets.RAILS_MASTER_KEY }}
|
53
55
|
TERRAFORM_PRE_RUN: |
|
54
56
|
apt-get update
|
data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml
CHANGED
@@ -47,8 +47,10 @@ jobs:
|
|
47
47
|
- name: Terraform apply
|
48
48
|
uses: dflook/terraform-apply@v1
|
49
49
|
env:
|
50
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
51
|
+
CF_USER: ${{ secrets.CF_USERNAME }}
|
52
|
+
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
|
50
53
|
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
51
|
-
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
52
54
|
TF_VAR_rails_master_key: ${{ secrets.RAILS_MASTER_KEY }}
|
53
55
|
TERRAFORM_PRE_RUN: |
|
54
56
|
apt-get update
|
@@ -57,8 +57,10 @@ jobs:
|
|
57
57
|
- name: terraform plan
|
58
58
|
uses: dflook/terraform-plan@v1
|
59
59
|
env:
|
60
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
61
|
+
CF_USER: ${{ secrets.CF_USERNAME }}
|
62
|
+
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
|
60
63
|
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
61
|
-
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
62
64
|
TF_VAR_rails_master_key: ${{ secrets.RAILS_MASTER_KEY }}
|
63
65
|
TERRAFORM_PRE_RUN: |
|
64
66
|
apt-get update
|
@@ -57,8 +57,10 @@ jobs:
|
|
57
57
|
- name: terraform plan
|
58
58
|
uses: dflook/terraform-plan@v1
|
59
59
|
env:
|
60
|
+
CF_API_URL: "https://api.fr.cloud.gov"
|
61
|
+
CF_USER: ${{ secrets.CF_USERNAME }}
|
62
|
+
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
|
60
63
|
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
61
|
-
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
62
64
|
TF_VAR_rails_master_key: ${{ secrets.RAILS_MASTER_KEY }}
|
63
65
|
TERRAFORM_PRE_RUN: |
|
64
66
|
apt-get update
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
module RailsTemplate18f
|
6
|
+
module Generators
|
7
|
+
class GitlabCiGenerator < ::Rails::Generators::Base
|
8
|
+
include Base
|
9
|
+
include CloudGovOptions
|
10
|
+
|
11
|
+
class_option :node_version, desc: "Node version to test against in actions"
|
12
|
+
class_option :postgres_version, default: "15", desc: "PostgreSQL version "
|
13
|
+
|
14
|
+
desc <<~DESC
|
15
|
+
Description:
|
16
|
+
Install GitLab CI workflow files
|
17
|
+
DESC
|
18
|
+
|
19
|
+
def install_actions
|
20
|
+
template "gitlab-ci.yml", ".gitlab-ci.yml"
|
21
|
+
directory "gitlab", ".gitlab"
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_readme
|
25
|
+
if file_content("README.md").match?(/^## CI\/CD$/)
|
26
|
+
insert_into_file "README.md", readme_cicd, after: "## CI/CD\n"
|
27
|
+
insert_into_file "README.md", readme_staging_deploy, after: "#### Staging\n"
|
28
|
+
insert_into_file "README.md", readme_prod_deploy, after: "#### Production\n"
|
29
|
+
insert_into_file "README.md", readme_credentials, after: "#### Credentials and other Secrets\n"
|
30
|
+
else
|
31
|
+
append_to_file "README.md", <<~EOM
|
32
|
+
## CI/CD
|
33
|
+
#{readme_cicd}
|
34
|
+
|
35
|
+
### Deployment
|
36
|
+
|
37
|
+
#### Staging
|
38
|
+
#{readme_staging_deploy}
|
39
|
+
|
40
|
+
#### Production
|
41
|
+
#{readme_prod_deploy}
|
42
|
+
|
43
|
+
#### Credentials and other Secrets
|
44
|
+
#{readme_credentials}
|
45
|
+
EOM
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_boundary_diagram
|
50
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
51
|
+
insert_into_file boundary_filename, <<EOB, after: "Boundary(cicd, \"CI/CD Pipeline\") {\n"
|
52
|
+
System_Ext(gitlabci, "GitLab w/ DevTools Runner", "GSA-controlled code repository and Continuous Integration Service")
|
53
|
+
EOB
|
54
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
55
|
+
Rel(developer, gitlabci, "Publish code", "git ssh (22)")
|
56
|
+
Rel(gitlabci, cg_api, "Deploy App", "Auth: SpaceDeployer Service Account, https (443)")
|
57
|
+
EOB
|
58
|
+
end
|
59
|
+
|
60
|
+
no_tasks do
|
61
|
+
def readme_cicd
|
62
|
+
<<~EOM
|
63
|
+
|
64
|
+
GitLab CI is used to run all tests and scans as part of pull requests.
|
65
|
+
|
66
|
+
Security scans are also run on a scheduled basis. DEVELOPER TODO: create a pipeline schedule in the GitLab UI and update this sentence with the cadence.
|
67
|
+
EOM
|
68
|
+
end
|
69
|
+
|
70
|
+
def readme_staging_deploy
|
71
|
+
<<~EOM
|
72
|
+
|
73
|
+
Deploys to staging happen via terraform on every push to the `main` branch in GitLab.
|
74
|
+
|
75
|
+
The following secrets must be set within the masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/)
|
76
|
+
|
77
|
+
| Secret Name | Description |
|
78
|
+
| ----------- | ----------- |
|
79
|
+
| `CF_USERNAME` | cloud.gov SpaceDeployer username |
|
80
|
+
| `CF_PASSWORD` | cloud.gov SpaceDeployer password |
|
81
|
+
| `RAILS_MASTER_KEY` | `config/master.key` |
|
82
|
+
EOM
|
83
|
+
end
|
84
|
+
|
85
|
+
def readme_prod_deploy
|
86
|
+
if terraform_manage_spaces?
|
87
|
+
<<~EOM
|
88
|
+
|
89
|
+
Deploys to production happen via terraform on every push to the `production` branch in GitLab.
|
90
|
+
|
91
|
+
The following secrets must be set within the masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/)
|
92
|
+
|
93
|
+
| Secret Name | Description |
|
94
|
+
| ----------- | ----------- |
|
95
|
+
| `CF_USERNAME` | cloud.gov SpaceDeployer username |
|
96
|
+
| `CF_PASSWORD` | cloud.gov SpaceDeployer password |
|
97
|
+
| `PRODUCTION_RAILS_MASTER_KEY` | `config/credentials/production.key`. Should be marked as `Protected`. |
|
98
|
+
EOM
|
99
|
+
else
|
100
|
+
"Production deploys are not supported in the sandbox organization."
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def readme_credentials
|
105
|
+
<<~EOM
|
106
|
+
|
107
|
+
1. Store variables that must be secret using masked and hidden [CI/CD variables](https://docs.gitlab.com/ci/variables/) in GitLab
|
108
|
+
1. Add the appropriate `-var` arguments to the `terraform:plan:<env>` and `terraform:apply:<env>` jobs like the existing `-var rails_master_key=`
|
109
|
+
EOM
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def postgres_version
|
116
|
+
options[:postgres_version]
|
117
|
+
end
|
118
|
+
|
119
|
+
def node_version
|
120
|
+
if options[:node_version].present?
|
121
|
+
options[:node_version]
|
122
|
+
elsif File.exist?(nvmrc_path)
|
123
|
+
File.read(nvmrc_path).strip
|
124
|
+
else
|
125
|
+
"20.16"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def node_major
|
130
|
+
node_version.split(".").first
|
131
|
+
end
|
132
|
+
|
133
|
+
def nvmrc_path
|
134
|
+
@nvmrc_path ||= File.expand_path(".nvmrc", destination_root)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.setup-node:
|
2
|
+
- curl -fsSL https://deb.nodesource.com/setup_<%= node_major %>.x -o nodesource_setup.sh
|
3
|
+
- bash nodesource_setup.sh
|
4
|
+
- apt-get install -y nodejs
|
5
|
+
- npm install --global yarn
|
6
|
+
|
7
|
+
.yarn-install:
|
8
|
+
- PUPPETEER_SKIP_DOWNLOAD=true yarn install --frozen-lockfile --no-progress
|
9
|
+
|
10
|
+
.install-puppet-deps:
|
11
|
+
- apt-get update && apt-get install -y chromium
|
@@ -0,0 +1,75 @@
|
|
1
|
+
include:
|
2
|
+
- local: ".gitlab/ruby.yml"
|
3
|
+
- local: ".gitlab/node.yml"
|
4
|
+
|
5
|
+
# Cache Helpers
|
6
|
+
.cache-dependencies:
|
7
|
+
variables:
|
8
|
+
WORKER_MEMORY: 2G
|
9
|
+
cache:
|
10
|
+
key:
|
11
|
+
files:
|
12
|
+
- Gemfile.lock
|
13
|
+
- yarn.lock
|
14
|
+
prefix: dependencies
|
15
|
+
paths:
|
16
|
+
- vendor/ruby
|
17
|
+
- node_modules/
|
18
|
+
policy: pull
|
19
|
+
|
20
|
+
# Language Helpers
|
21
|
+
.setup-languages:
|
22
|
+
before_script:
|
23
|
+
- !reference [.setup-ruby]
|
24
|
+
- !reference [.setup-node]
|
25
|
+
|
26
|
+
# Project Helpers
|
27
|
+
.setup-project:
|
28
|
+
services:
|
29
|
+
- name: "postgres:${POSTGRES_VERSION}"
|
30
|
+
alias: pg
|
31
|
+
before_script:
|
32
|
+
- !reference [.setup-ruby]
|
33
|
+
- export DATABASE_URL="postgres://postgres:${POSTGRES_PASSWORD}@${WSR_SERVICE_HOST_pg}:5432/${POSTGRES_DB}"
|
34
|
+
- bin/rails db:prepare
|
35
|
+
|
36
|
+
.run-server:
|
37
|
+
extends: .setup-project
|
38
|
+
dependencies: []
|
39
|
+
variables:
|
40
|
+
RAILS_ENV: ci
|
41
|
+
SECRET_KEY_BASE_DUMMY: 1
|
42
|
+
before_script:
|
43
|
+
- !reference [.setup-node]
|
44
|
+
- !reference [.setup-project, before_script]
|
45
|
+
- bin/rake assets:precompile
|
46
|
+
- PORT=3000 bin/rails server > /dev/null 2>&1 &
|
47
|
+
- sleep 5
|
48
|
+
|
49
|
+
.owasp:setup:
|
50
|
+
stage: scan
|
51
|
+
extends: .run-server
|
52
|
+
image: "rcahearngsa/owasp-ruby:${RUBY_VERSION}"
|
53
|
+
variables:
|
54
|
+
WORKER_MEMORY: 3G
|
55
|
+
WORKER_DISK: 6G
|
56
|
+
before_script:
|
57
|
+
- !reference [.run-server, before_script]
|
58
|
+
- ln -s $PWD /zap/wrk
|
59
|
+
artifacts:
|
60
|
+
expose_as: "OWASP Report"
|
61
|
+
paths:
|
62
|
+
- zap_report.html
|
63
|
+
|
64
|
+
.assets:builder:
|
65
|
+
stage: deploy
|
66
|
+
extends: .setup-languages
|
67
|
+
dependencies: []
|
68
|
+
variables:
|
69
|
+
SECRET_KEY_BASE_DUMMY: 1
|
70
|
+
script:
|
71
|
+
- bin/rake assets:precompile
|
72
|
+
- bin/rake assets:clean
|
73
|
+
artifacts:
|
74
|
+
paths:
|
75
|
+
- public/assets
|