cpl 1.3.0 → 2.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/command_docs.yml +1 -1
  3. data/.github/workflows/rspec-shared.yml +56 -0
  4. data/.github/workflows/rspec.yml +19 -31
  5. data/.github/workflows/rubocop.yml +2 -10
  6. data/.gitignore +2 -0
  7. data/.simplecov_spawn.rb +10 -0
  8. data/CHANGELOG.md +28 -1
  9. data/CONTRIBUTING.md +32 -2
  10. data/Gemfile.lock +38 -29
  11. data/README.md +43 -17
  12. data/cpl.gemspec +2 -1
  13. data/docs/commands.md +68 -59
  14. data/docs/dns.md +6 -0
  15. data/docs/migrating.md +10 -10
  16. data/docs/tips.md +15 -3
  17. data/examples/circleci.yml +3 -3
  18. data/examples/controlplane.yml +35 -9
  19. data/lib/command/apply_template.rb +66 -18
  20. data/lib/command/base.rb +168 -27
  21. data/lib/command/build_image.rb +4 -9
  22. data/lib/command/cleanup_stale_apps.rb +1 -3
  23. data/lib/command/copy_image_from_upstream.rb +0 -7
  24. data/lib/command/delete.rb +39 -7
  25. data/lib/command/deploy_image.rb +35 -2
  26. data/lib/command/exists.rb +1 -1
  27. data/lib/command/generate.rb +1 -1
  28. data/lib/command/info.rb +7 -3
  29. data/lib/command/logs.rb +22 -2
  30. data/lib/command/maintenance_off.rb +1 -1
  31. data/lib/command/maintenance_on.rb +1 -1
  32. data/lib/command/open.rb +2 -2
  33. data/lib/command/open_console.rb +2 -2
  34. data/lib/command/promote_app_from_upstream.rb +5 -25
  35. data/lib/command/ps.rb +1 -1
  36. data/lib/command/ps_start.rb +2 -1
  37. data/lib/command/ps_stop.rb +40 -8
  38. data/lib/command/ps_wait.rb +3 -2
  39. data/lib/command/run.rb +430 -68
  40. data/lib/command/setup_app.rb +22 -2
  41. data/lib/constants/exit_code.rb +7 -0
  42. data/lib/core/config.rb +11 -3
  43. data/lib/core/controlplane.rb +126 -47
  44. data/lib/core/controlplane_api.rb +15 -1
  45. data/lib/core/controlplane_api_cli.rb +3 -3
  46. data/lib/core/controlplane_api_direct.rb +33 -5
  47. data/lib/core/shell.rb +15 -9
  48. data/lib/cpl/version.rb +1 -1
  49. data/lib/cpl.rb +50 -9
  50. data/lib/deprecated_commands.json +2 -1
  51. data/lib/generator_templates/controlplane.yml +5 -0
  52. data/lib/generator_templates/templates/{gvc.yml → app.yml} +4 -4
  53. data/lib/generator_templates/templates/postgres.yml +1 -1
  54. data/lib/generator_templates/templates/rails.yml +1 -1
  55. data/script/check_cpln_links +3 -3
  56. data/templates/app.yml +18 -0
  57. data/templates/daily-task.yml +3 -2
  58. data/templates/rails.yml +3 -2
  59. data/templates/secrets.yml +11 -0
  60. data/templates/sidekiq.yml +3 -2
  61. metadata +38 -25
  62. data/.rspec +0 -1
  63. data/lib/command/run_cleanup.rb +0 -116
  64. data/lib/command/run_detached.rb +0 -175
  65. data/lib/core/scripts.rb +0 -34
  66. data/templates/gvc.yml +0 -13
  67. data/templates/identity.yml +0 -2
data/docs/commands.md CHANGED
@@ -21,10 +21,14 @@ This `-a` option is used in most of the commands and will pick all other app con
21
21
  **Preprocessed template variables:**
22
22
 
23
23
  ```
24
- APP_GVC - basically GVC or app name
25
- APP_LOCATION - default location
26
- APP_ORG - organization
27
- APP_IMAGE - will use latest app image
24
+ {{APP_ORG}} - organization name
25
+ {{APP_NAME}} - GVC/app name
26
+ {{APP_LOCATION}} - location, per YML file, ENV, or command line arg
27
+ {{APP_LOCATION_LINK}} - full link for location, ready to be used for the value of `staticPlacement.locationLinks` in the templates
28
+ {{APP_IMAGE}} - latest app image
29
+ {{APP_IMAGE_LINK}} - full link for latest app image, ready to be used for the value of `containers[].image` in the templates
30
+ {{APP_IDENTITY}} - default identity
31
+ {{APP_IDENTITY_LINK}} - full link for identity, ready to be used for the value of `identityLink` in the templates
28
32
  ```
29
33
 
30
34
  ```sh
@@ -32,7 +36,7 @@ APP_IMAGE - will use latest app image
32
36
  cpl apply-template redis -a $APP_NAME
33
37
 
34
38
  # Applies several templates (practically creating full app).
35
- cpl apply-template gvc postgres redis rails -a $APP_NAME
39
+ cpl apply-template app postgres redis rails -a $APP_NAME
36
40
  ```
37
41
 
38
42
  ### `build-image`
@@ -101,16 +105,23 @@ cpl copy-image-from-upstream -a $APP_NAME --upstream-token $UPSTREAM_TOKEN --ima
101
105
 
102
106
  ### `delete`
103
107
 
104
- - Deletes the whole app (GVC with all workloads, all volumesets and all images)
108
+ - Deletes the whole app (GVC with all workloads, all volumesets and all images) or a specific workload
105
109
  - Will ask for explicit user confirmation
106
110
 
107
111
  ```sh
112
+ # Deletes the whole app (GVC with all workloads, all volumesets and all images).
108
113
  cpl delete -a $APP_NAME
114
+
115
+ # Deletes a specific workload.
116
+ cpl delete -a $APP_NAME -w $WORKLOAD_NAME
109
117
  ```
110
118
 
111
119
  ### `deploy-image`
112
120
 
113
121
  - Deploys the latest image to app workloads
122
+ - Optionally runs a release script before deploying if specified through `release_script` in the `.controlplane/controlplane.yml` file and `--run-release-phase` is provided
123
+ - The release script is run in the context of `cpl run` with the latest image
124
+ - The deploy will fail if the release script exits with a non-zero code or doesn't exist
114
125
 
115
126
  ```sh
116
127
  cpl deploy-image -a $APP_NAME
@@ -171,6 +182,7 @@ cpl latest-image -a $APP_NAME
171
182
  ### `logs`
172
183
 
173
184
  - Light wrapper to display tailed raw logs for app/workload syntax
185
+ - Defaults to showing the last 200 entries from the past 1 hour before tailing
174
186
 
175
187
  ```sh
176
188
  # Displays logs for the default workload (`one_off_workload`).
@@ -178,6 +190,15 @@ cpl logs -a $APP_NAME
178
190
 
179
191
  # Displays logs for a specific workload.
180
192
  cpl logs -a $APP_NAME -w $WORKLOAD_NAME
193
+
194
+ # Displays logs for a specific replica of a workload.
195
+ cpl logs -a $APP_NAME -w $WORKLOAD_NAME -r $REPLICA_NAME
196
+
197
+ # Uses a different limit on number of entries.
198
+ cpl logs -a $APP_NAME --limit 100
199
+
200
+ # Uses a different loopback window.
201
+ cpl logs -a $APP_NAME --since 30min
181
202
  ```
182
203
 
183
204
  ### `maintenance`
@@ -251,8 +272,9 @@ cpl open-console -a $APP_NAME
251
272
  - Copies the latest image from upstream, runs a release script (optional), and deploys the image
252
273
  - It performs the following steps:
253
274
  - Runs `cpl copy-image-from-upstream` to copy the latest image from upstream
254
- - Runs a release script if specified through `release_script` in the `.controlplane/controlplane.yml` file
255
275
  - Runs `cpl deploy-image` to deploy the image
276
+ - If `.controlplane/controlplane.yml` includes the `release_script`, `cpl deploy-image` will use the `--run-release-phase` option
277
+ - The deploy will fail if the release script exits with a non-zero code
256
278
 
257
279
  ```sh
258
280
  cpl promote-app-from-upstream -a $APP_NAME -t $UPSTREAM_TOKEN
@@ -304,6 +326,9 @@ cpl ps:stop -a $APP_NAME
304
326
 
305
327
  # Stops a specific workload in app.
306
328
  cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
329
+
330
+ # Stops a specific replica of a workload.
331
+ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME -r $REPLICA_NAME
307
332
  ```
308
333
 
309
334
  ### `ps:wait`
@@ -320,26 +345,43 @@ cpl ps:swait -a $APP_NAME -w $WORKLOAD_NAME
320
345
 
321
346
  ### `run`
322
347
 
323
- - Runs one-off **_interactive_** replicas (analog of `heroku run`)
324
- - Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
325
- - If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file, the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
326
-
327
- > **IMPORTANT:** Useful for development where it's needed for interaction, and where network connection drops and
328
- > task crashing are tolerable. For production tasks, it's better to use `cpl run:detached`.
348
+ - Runs one-off interactive or non-interactive replicas (analog of `heroku run`)
349
+ - Uses `Cron` workload type and either:
350
+ - - `cpln workload exec` for interactive mode, with CLI streaming
351
+ - - log async fetching for non-interactive mode
352
+ - The Dockerfile entrypoint is used as the command by default, which assumes `exec "${@}"` to be present,
353
+ and the args ["bash", "-c", cmd_to_run] are passed
354
+ - The entrypoint can be overriden through `--entrypoint`, which must be a single command or a script path that exists in the container,
355
+ and the args ["bash", "-c", cmd_to_run] are passed,
356
+ unless the entrypoint is `bash`, in which case the args ["-c", cmd_to_run] are passed
357
+ - Providing `--entrypoint none` sets the entrypoint to `bash` by default
358
+ - If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file,
359
+ the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
329
360
 
330
361
  ```sh
331
362
  # Opens shell (bash by default).
332
363
  cpl run -a $APP_NAME
333
364
 
334
- # Need to quote COMMAND if setting ENV value or passing args.
335
- cpl run -a $APP_NAME -- 'LOG_LEVEL=warn rails db:migrate'
365
+ # Runs interactive command, keeps shell open, and stops job when exiting.
366
+ cpl run -a $APP_NAME --interactive -- rails c
336
367
 
337
- # Runs command, displays output, and exits shell.
338
- cpl run -a $APP_NAME -- ls /
339
- cpl run -a $APP_NAME -- rails db:migrate:status
368
+ # Some commands are automatically detected as interactive, so no need to pass `--interactive`.
369
+ cpl run -a $APP_NAME -- bash
370
+ cpl run -a $APP_NAME -- rails console
371
+ cpl run -a $APP_NAME -- rails c
372
+ cpl run -a $APP_NAME -- rails dbconsole
373
+ cpl run -a $APP_NAME -- rails db
340
374
 
341
- # Runs command and keeps shell open.
342
- cpl run -a $APP_NAME -- rails c
375
+ # Runs non-interactive command, outputs logs, exits with the exit code of the command and stops job.
376
+ cpl run -a $APP_NAME -- rails db:migrate
377
+
378
+ # Runs non-iteractive command, detaches, exits with 0, and prints commands to:
379
+ # - see logs from the job
380
+ # - stop the job
381
+ cpl run -a $APP_NAME --detached -- rails db:migrate
382
+
383
+ # The command needs to be quoted if setting an env variable or passing args.
384
+ cpl run -a $APP_NAME -- 'SOME_ENV_VAR=some_value rails db:migrate'
343
385
 
344
386
  # Uses a different image (which may not be promoted yet).
345
387
  cpl run -a $APP_NAME --image appimage:123 -- rails db:migrate # Exact image name
@@ -351,47 +393,12 @@ cpl run -a $APP_NAME -w other-workload -- bash
351
393
  # Overrides remote CPLN_TOKEN env variable with local token.
352
394
  # Useful when superuser rights are needed in remote container.
353
395
  cpl run -a $APP_NAME --use-local-token -- bash
354
- ```
355
-
356
- ### `run:cleanup`
357
-
358
- - Deletes stale run workloads for an app
359
- - Workloads are considered stale based on how many days since created
360
- - `stale_run_workload_created_days` in the `.controlplane/controlplane.yml` file specifies the number of days after created that the workload is considered stale
361
- - Works for both interactive workloads (created with `cpl run`) and non-interactive workloads (created with `cpl run:detached`)
362
- - Will ask for explicit user confirmation of deletion
363
-
364
- ```sh
365
- cpl run:cleanup -a $APP_NAME
366
- ```
367
-
368
- ### `run:detached`
369
-
370
- - Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)
371
- - Uses `Cron` workload type with log async fetching
372
- - Implemented with only async execution methods, more suitable for production tasks
373
- - Has alternative log fetch implementation with only JSON-polling and no WebSockets
374
- - Less responsive but more stable, useful for CI tasks
375
- - Deletes the workload whenever finished with success
376
- - Deletes the workload whenever finished with failure by default
377
- - Use `--no-clean-on-failure` to disable cleanup to help with debugging failed runs
378
-
379
- ```sh
380
- cpl run:detached rails db:prepare -a $APP_NAME
381
396
 
382
- # Need to quote COMMAND if setting ENV value or passing args.
383
- cpl run:detached -a $APP_NAME -- 'LOG_LEVEL=warn rails db:migrate'
397
+ # Replaces the existing Dockerfile entrypoint with `bash`.
398
+ cpl run -a $APP_NAME --entrypoint none -- rails db:migrate
384
399
 
385
- # Uses a different image (which may not be promoted yet).
386
- cpl run:detached -a $APP_NAME --image appimage:123 -- rails db:migrate # Exact image name
387
- cpl run:detached -a $APP_NAME --image latest -- rails db:migrate # Latest sequential image
388
-
389
- # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
390
- cpl run:detached -a $APP_NAME -w other-workload -- rails db:migrate:status
391
-
392
- # Overrides remote CPLN_TOKEN env variable with local token.
393
- # Useful when superuser rights are needed in remote container.
394
- cpl run:detached -a $APP_NAME --use-local-token -- rails db:migrate:status
400
+ # Replaces the existing Dockerfile entrypoint.
401
+ cpl run -a $APP_NAME --entrypoint /app/alternative-entrypoint.sh -- rails db:migrate
395
402
  ```
396
403
 
397
404
  ### `setup-app`
@@ -399,6 +406,8 @@ cpl run:detached -a $APP_NAME --use-local-token -- rails db:migrate:status
399
406
  - Creates an app and all its workloads
400
407
  - Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
401
408
  - This should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
409
+ - Automatically binds the app to the secrets policy, as long as both the identity and the policy exist
410
+ - Use `--skip-secret-access-binding` to prevent the automatic bind
402
411
 
403
412
  ```sh
404
413
  cpl setup-app -a $APP_NAME
data/docs/dns.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # DNS Setup Example
2
2
 
3
+ ## Docs
4
+
5
+ https://shakadocs.controlplane.com/guides/configure-domain#dns-records
6
+
7
+ ## Example
8
+
3
9
  About reactrails.com DNS, steps:
4
10
  1. create CNAME or ALIAS record pointing to rails-xxxx.cpln.app
5
11
  1. go to CPLN Domains -> create
data/docs/migrating.md CHANGED
@@ -36,7 +36,7 @@ key, e.g.:
36
36
  my-app-staging:
37
37
  <<: *common
38
38
  setup_app_templates:
39
- - gvc
39
+ - app
40
40
  - redis
41
41
  - memcached
42
42
  - rails
@@ -46,8 +46,8 @@ my-app-staging:
46
46
  Note how the templates correspond to files in the `.controlplane/templates/` directory. These files will be used by the
47
47
  `cpl setup-app` and `cpl apply-template` commands.
48
48
 
49
- Ensure that env vars point to the Heroku add-ons in the template for the app (`.controlplane/templates/gvc.yml`). See
50
- [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/templates/gvc.yml).
49
+ Ensure that env vars point to the Heroku add-ons in the template for the app (`.controlplane/templates/app.yml`). See
50
+ [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/templates/app.yml).
51
51
 
52
52
  After that, create a Dockerfile in `.controlplane/Dockerfile` for your deployment. See
53
53
  [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/Dockerfile).
@@ -61,7 +61,7 @@ app_main_folder/
61
61
  controlplane.yml
62
62
  entrypoint.sh # App-specific - edit as needed.
63
63
  templates/
64
- gvc.yml
64
+ app.yml
65
65
  memcached.yml
66
66
  rails.yml
67
67
  redis.yml
@@ -93,7 +93,7 @@ cpl setup-app -a my-app-staging
93
93
  cpl build-image -a my-app-staging --commit 456
94
94
 
95
95
  # Prepare database.
96
- cpl run:detached -a my-app-staging --image latest -- rails db:prepare
96
+ cpl run -a my-app-staging --image latest -- rails db:prepare
97
97
 
98
98
  # Deploy latest image.
99
99
  cpl deploy-image -a my-app-staging
@@ -113,7 +113,7 @@ cpl build-image -a my-app-staging --commit ABC
113
113
 
114
114
  # Run database migrations (or other release tasks) with latest image, while app is still running on previous image.
115
115
  # This is analogous to the release phase.
116
- cpl run:detached -a my-app-staging --image latest -- rails db:migrate
116
+ cpl run -a my-app-staging --image latest -- rails db:migrate
117
117
 
118
118
  # Deploy latest image.
119
119
  cpl deploy-image -a my-app-staging
@@ -192,7 +192,7 @@ configure an entry for, e.g., `my-app-review`, and then create review apps start
192
192
  <<: *common
193
193
  match_if_app_name_starts_with: true
194
194
  setup_app_templates:
195
- - gvc
195
+ - app
196
196
  - redis
197
197
  - memcached
198
198
  - rails
@@ -215,9 +215,9 @@ fi
215
215
 
216
216
  # The `NEW_APP` env var that we exported above can be used to either reset or migrate the database before deploying.
217
217
  if [ -n "${NEW_APP}" ]; then
218
- cpl run:detached 'LOG_LEVEL=warn rails db:reset' -a ${APP_NAME} --image latest
218
+ cpl run -a ${APP_NAME} --image latest -- rails db:reset
219
219
  else
220
- cpl run:detached 'LOG_LEVEL=warn rails db:migrate_and_wait_replica' -a ${APP_NAME} --image latest
220
+ cpl run -a ${APP_NAME} --image latest -- rails db:migrate
221
221
  fi
222
222
  ```
223
223
 
@@ -226,7 +226,7 @@ Then follow the same steps for the initial deployment or code upgrades.
226
226
  ### Database for Review Apps
227
227
 
228
228
  For the review app resources, these should be handled as env vars in the template for the app
229
- (`.controlplane/templates/gvc.yml`), .e.g.:
229
+ (`.controlplane/templates/app.yml`), .e.g.:
230
230
 
231
231
  ```yaml
232
232
  - name: DATABASE_URL
data/docs/tips.md CHANGED
@@ -65,7 +65,7 @@ The actual remote IP of the workload container is in the 127.0.0.x network, so t
65
65
  `REMOTE_ADDR` env var.
66
66
 
67
67
  However, Control Plane additionally sets the `x-forwarded-for` and `x-envoy-external-address` headers (and others - see:
68
- https://docs.controlplane.com/concepts/security#headers). On Rails, the `ActionDispatch::RemoteIp` middleware should
68
+ https://shakadocs.controlplane.com/concepts/security#headers). On Rails, the `ActionDispatch::RemoteIp` middleware should
69
69
  pick those up and automatically populate `request.remote_ip`.
70
70
 
71
71
  So `REMOTE_ADDR` should not be used directly, only `request.remote_ip`.
@@ -85,9 +85,21 @@ For storing ENVs in the source code, we can use a level of indirection so that y
85
85
  code like `cpln://secret/my-app-review-env-secrets.SECRET_KEY_BASE` and then have the secret value stored at the org
86
86
  level, which applies to your GVCs mapped to that org.
87
87
 
88
- Here is how you do this:
88
+ You can do this during the initial app setup, like this:
89
89
 
90
- 1. In the upper left "Manage Org" menu, click on "Secrets"
90
+ 1. Add the templates for `app` and `secrets` to `.controlplane/templates`
91
+ 2. Ensure that the `app` template includes the `identity`
92
+ 3. Ensure that the `app` template is listed in `setup_app_templates` for the app in `.controlplane/controlplane.yml`
93
+ 4. Run `cpl apply-template secrets -a $APP_NAME` (one-time setup)
94
+ 5. Run `cpl setup-app -a $APP_NAME`
95
+ 6. The secrets, secrets policy and identity will be automatically created, along with the proper binding
96
+ 7. In the Control Plane console, upper left "Manage Org" menu, click on "Secrets"
97
+ 8. Find the created secret (it will be in the `$APP_PREFIX-secrets` format) and add the secret env vars there
98
+ 9. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/$APP_PREFIX-secrets.SOME_VAR`)
99
+
100
+ Here are the manual steps for reference. We recommend that you follow the steps above:
101
+
102
+ 1. In the upper left of the Control Plane console, "Manage Org" menu, click on "Secrets"
91
103
  2. Create a secret with `Secret Type: Dictionary` (e.g., `my-secrets`) and add the secret env vars there
92
104
  3. In the upper left "Manage GVC" menu, click on "Identities"
93
105
  4. Create an identity (e.g., `my-identity`)
@@ -27,7 +27,7 @@ build-staging:
27
27
  command: cpl build-image -a ${APP_NAME}
28
28
  - run:
29
29
  name: Database tasks
30
- command: cpl run:detached -a ${APP_NAME} --image latest -- rails db:migrate
30
+ command: cpl run -a ${APP_NAME} --image latest -- rails db:migrate
31
31
  - run:
32
32
  name: Deploy image
33
33
  command: cpl deploy-image -a ${APP_NAME}
@@ -75,9 +75,9 @@ build-review-app:
75
75
  name: Database tasks
76
76
  command: |
77
77
  if [ -n "${NEW_APP}" ]; then
78
- cpl run:detached -a ${APP_NAME} --image latest -- LOG_LEVEL=warn rails db:reset
78
+ cpl run -a ${APP_NAME} --image latest -- rails db:reset
79
79
  else
80
- cpl run:detached -a ${APP_NAME} --image latest -- LOG_LEVEL=warn rails db:migrate
80
+ cpl run -a ${APP_NAME} --image latest -- rails db:migrate
81
81
  fi
82
82
  - run:
83
83
  name: Deploy image
@@ -17,31 +17,61 @@ aliases:
17
17
 
18
18
  # Control Plane offers the ability to use multiple locations.
19
19
  # default_location is used for commands that require a location
20
- # including `ps`, `run`, `run:detached`, `apply-template`.
20
+ # including `ps`, `run`, `apply-template`.
21
21
  # This can be overridden with option --location=<location> and
22
22
  # CPLN_LOCATION environment variable.
23
23
  # TODO: Allow specification of multiple locations.
24
24
  default_location: aws-us-east-2
25
25
 
26
26
  # Allows running the command `cpl setup-app`
27
- # instead of `cpl apply-template gvc redis postgres memcached rails sidekiq`.
28
- setup:
29
- - gvc
27
+ # instead of `cpl apply-template app redis postgres memcached rails sidekiq`.
28
+ #
29
+ # Note:
30
+ # 1. These names correspond to files in the `./controlplane/templates` directory.
31
+ # 2. Each file can contain many objects, such as in the case of templates that create a resource, like `postgres`.
32
+ # 3. While the naming often corresponds to a workload or other object name, the naming is arbitrary.
33
+ # Naming does not need to match anything other than the file name without the `.yml` extension.
34
+ #
35
+ # If you're going to use secrets, you need to apply the `secrets.yml` template separately (one-time setup):
36
+ # `cpl apply-template secrets -a my-app`
37
+ setup_app_templates:
38
+ - app
30
39
  - redis
31
40
  - postgres
32
41
  - memcached
33
42
  - rails
34
43
  - sidekiq
35
44
 
45
+ # Only needed if using a custom secrets name.
46
+ # The default is '{APP_PREFIX}-secrets'. For example:
47
+ # - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
48
+ # it would be 'my-app-staging-secrets'
49
+ # - for an app 'my-app-review-1234' with `match_if_app_name_starts_with` set to `true`,
50
+ # it would be 'my-app-review-secrets'
51
+ secrets_name: my-secrets
52
+
53
+ # Only needed if using a custom secrets policy name.
54
+ # The default is '{APP_SECRETS}-policy'. For example:
55
+ # - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
56
+ # it would be 'my-app-staging-secrets-policy'
57
+ # - for an app 'my-app-review-1234' with `match_if_app_name_starts_with` set to `true`,
58
+ # it would be 'my-app-review-secrets-policy'
59
+ secrets_policy_name: my-secrets-policy
60
+
36
61
  # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
37
62
  one_off_workload: rails
38
63
 
39
64
  # Workloads that are for the application itself and are using application Docker images.
65
+ # These are updated with the new image when running the `deploy-image` command,
66
+ # and are also used by the `info` and `ps:` commands in order to get all of the defined workloads.
67
+ # On the other hand, if you have a workload for Redis, that would NOT use the application Docker image
68
+ # and not be listed here.
40
69
  app_workloads:
41
70
  - rails
42
71
  - sidekiq
43
72
 
44
73
  # Additional "service type" workloads, using non-application Docker images.
74
+ # These are only used by the `info` and `ps:` commands in order to get all of the defined workloads.
45
75
  additional_workloads:
46
76
  - redis
47
77
  - postgres
@@ -51,7 +81,7 @@ aliases:
51
81
  maintenance_workload: maintenance
52
82
 
53
83
  # Fixes the remote terminal size to match the local terminal size
54
- # when running the commands `cpl run` or `cpl run:detached`.
84
+ # when running `cpl run`.
55
85
  fix_terminal_size: true
56
86
 
57
87
  # Apps with a deployed image created before this amount of days will be listed for deletion
@@ -66,10 +96,6 @@ aliases:
66
96
  # when running the command `cpl cleanup-images` (`image_retention_max_qty` takes precedence).
67
97
  image_retention_days: 5
68
98
 
69
- # Run workloads created before this amount of days will be listed for deletion
70
- # when running the command `cpl run:cleanup`.
71
- stale_run_workload_created_days: 2
72
-
73
99
  apps:
74
100
  my-app-staging:
75
101
  # Use the values from the common section above.
@@ -20,10 +20,14 @@ module Command
20
20
  **Preprocessed template variables:**
21
21
 
22
22
  ```
23
- APP_GVC - basically GVC or app name
24
- APP_LOCATION - default location
25
- APP_ORG - organization
26
- APP_IMAGE - will use latest app image
23
+ {{APP_ORG}} - organization name
24
+ {{APP_NAME}} - GVC/app name
25
+ {{APP_LOCATION}} - location, per YML file, ENV, or command line arg
26
+ {{APP_LOCATION_LINK}} - full link for location, ready to be used for the value of `staticPlacement.locationLinks` in the templates
27
+ {{APP_IMAGE}} - latest app image
28
+ {{APP_IMAGE_LINK}} - full link for latest app image, ready to be used for the value of `containers[].image` in the templates
29
+ {{APP_IDENTITY}} - default identity
30
+ {{APP_IDENTITY_LINK}} - full link for identity, ready to be used for the value of `identityLink` in the templates
27
31
  ```
28
32
  DESC
29
33
  EXAMPLES = <<~EX
@@ -32,11 +36,11 @@ module Command
32
36
  cpl apply-template redis -a $APP_NAME
33
37
 
34
38
  # Applies several templates (practically creating full app).
35
- cpl apply-template gvc postgres redis rails -a $APP_NAME
39
+ cpl apply-template app postgres redis rails -a $APP_NAME
36
40
  ```
37
41
  EX
38
42
 
39
- def call # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
43
+ def call # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
40
44
  ensure_templates!
41
45
 
42
46
  @created_items = []
@@ -46,7 +50,7 @@ module Command
46
50
  @asked_for_confirmation = false
47
51
 
48
52
  pending_templates = templates.select do |template|
49
- if template == "gvc"
53
+ if template == "app"
50
54
  confirm_app(template)
51
55
  else
52
56
  confirm_workload(template)
@@ -55,24 +59,30 @@ module Command
55
59
 
56
60
  progress.puts if @asked_for_confirmation
57
61
 
62
+ @deprecated_variables = []
63
+
58
64
  pending_templates.each do |template, filename|
59
65
  step("Applying template '#{template}'", abort_on_error: false) do
60
66
  items = apply_template(filename)
61
- if items
62
- items.each do |item|
63
- report_success(item)
64
- end
65
- else
67
+ unless items
66
68
  report_failure(template)
69
+ next false
67
70
  end
68
71
 
69
- $CHILD_STATUS.success?
72
+ items.each do |item|
73
+ report_success(item)
74
+ end
75
+ true
70
76
  end
71
77
  end
72
78
 
79
+ warn_deprecated_variables
80
+
73
81
  print_created_items
74
82
  print_failed_templates
75
83
  print_skipped_templates
84
+
85
+ exit(ExitCode::ERROR_DEFAULT) if @failed_templates.any?
76
86
  end
77
87
 
78
88
  private
@@ -124,17 +134,55 @@ module Command
124
134
  false
125
135
  end
126
136
 
127
- def apply_template(filename)
137
+ def apply_template(filename) # rubocop:disable Metrics/MethodLength
128
138
  data = File.read(filename)
129
- .gsub("APP_GVC", config.app)
130
- .gsub("APP_LOCATION", config.location)
131
- .gsub("APP_ORG", config.org)
132
- .gsub("APP_IMAGE", latest_image)
139
+ .gsub("{{APP_ORG}}", config.org)
140
+ .gsub("{{APP_NAME}}", config.app)
141
+ .gsub("{{APP_LOCATION}}", config.location)
142
+ .gsub("{{APP_LOCATION_LINK}}", app_location_link)
143
+ .gsub("{{APP_IMAGE}}", latest_image)
144
+ .gsub("{{APP_IMAGE_LINK}}", app_image_link)
145
+ .gsub("{{APP_IDENTITY}}", app_identity)
146
+ .gsub("{{APP_IDENTITY_LINK}}", app_identity_link)
147
+ .gsub("{{APP_SECRETS}}", app_secrets)
148
+ .gsub("{{APP_SECRETS_POLICY}}", app_secrets_policy)
149
+
150
+ find_deprecated_variables(data)
151
+
152
+ # Kept for backwards compatibility
153
+ data = data
154
+ .gsub("APP_ORG", config.org)
155
+ .gsub("APP_GVC", config.app)
156
+ .gsub("APP_LOCATION", config.location)
157
+ .gsub("APP_IMAGE", latest_image)
133
158
 
134
159
  # Don't read in YAML.safe_load as that doesn't handle multiple documents
135
160
  cp.apply_template(data)
136
161
  end
137
162
 
163
+ def new_variables
164
+ {
165
+ "APP_ORG" => "{{APP_ORG}}",
166
+ "APP_GVC" => "{{APP_NAME}}",
167
+ "APP_LOCATION" => "{{APP_LOCATION}}",
168
+ "APP_IMAGE" => "{{APP_IMAGE}}"
169
+ }
170
+ end
171
+
172
+ def find_deprecated_variables(data)
173
+ @deprecated_variables.push(*new_variables.keys.select { |old_key| data.include?(old_key) })
174
+ @deprecated_variables = @deprecated_variables.uniq.sort
175
+ end
176
+
177
+ def warn_deprecated_variables
178
+ return unless @deprecated_variables.any?
179
+
180
+ message = "Please replace these variables in the templates, " \
181
+ "as support for them will be removed in a future major version bump:"
182
+ deprecated = @deprecated_variables.map { |old_key| " - #{old_key} -> #{new_variables[old_key]}" }.join("\n")
183
+ progress.puts("\n#{Shell.color("DEPRECATED: #{message}", :yellow)}\n#{deprecated}")
184
+ end
185
+
138
186
  def report_success(item)
139
187
  @created_items.push(item)
140
188
  end