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.
- checksums.yaml +4 -4
- data/.github/workflows/command_docs.yml +1 -1
- data/.github/workflows/rspec-shared.yml +56 -0
- data/.github/workflows/rspec.yml +19 -31
- data/.github/workflows/rubocop.yml +2 -10
- data/.gitignore +2 -0
- data/.simplecov_spawn.rb +10 -0
- data/CHANGELOG.md +28 -1
- data/CONTRIBUTING.md +32 -2
- data/Gemfile.lock +38 -29
- data/README.md +43 -17
- data/cpl.gemspec +2 -1
- data/docs/commands.md +68 -59
- data/docs/dns.md +6 -0
- data/docs/migrating.md +10 -10
- data/docs/tips.md +15 -3
- data/examples/circleci.yml +3 -3
- data/examples/controlplane.yml +35 -9
- data/lib/command/apply_template.rb +66 -18
- data/lib/command/base.rb +168 -27
- data/lib/command/build_image.rb +4 -9
- data/lib/command/cleanup_stale_apps.rb +1 -3
- data/lib/command/copy_image_from_upstream.rb +0 -7
- data/lib/command/delete.rb +39 -7
- data/lib/command/deploy_image.rb +35 -2
- data/lib/command/exists.rb +1 -1
- data/lib/command/generate.rb +1 -1
- data/lib/command/info.rb +7 -3
- data/lib/command/logs.rb +22 -2
- data/lib/command/maintenance_off.rb +1 -1
- data/lib/command/maintenance_on.rb +1 -1
- data/lib/command/open.rb +2 -2
- data/lib/command/open_console.rb +2 -2
- data/lib/command/promote_app_from_upstream.rb +5 -25
- data/lib/command/ps.rb +1 -1
- data/lib/command/ps_start.rb +2 -1
- data/lib/command/ps_stop.rb +40 -8
- data/lib/command/ps_wait.rb +3 -2
- data/lib/command/run.rb +430 -68
- data/lib/command/setup_app.rb +22 -2
- data/lib/constants/exit_code.rb +7 -0
- data/lib/core/config.rb +11 -3
- data/lib/core/controlplane.rb +126 -47
- data/lib/core/controlplane_api.rb +15 -1
- data/lib/core/controlplane_api_cli.rb +3 -3
- data/lib/core/controlplane_api_direct.rb +33 -5
- data/lib/core/shell.rb +15 -9
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +50 -9
- data/lib/deprecated_commands.json +2 -1
- data/lib/generator_templates/controlplane.yml +5 -0
- data/lib/generator_templates/templates/{gvc.yml → app.yml} +4 -4
- data/lib/generator_templates/templates/postgres.yml +1 -1
- data/lib/generator_templates/templates/rails.yml +1 -1
- data/script/check_cpln_links +3 -3
- data/templates/app.yml +18 -0
- data/templates/daily-task.yml +3 -2
- data/templates/rails.yml +3 -2
- data/templates/secrets.yml +11 -0
- data/templates/sidekiq.yml +3 -2
- metadata +38 -25
- data/.rspec +0 -1
- data/lib/command/run_cleanup.rb +0 -116
- data/lib/command/run_detached.rb +0 -175
- data/lib/core/scripts.rb +0 -34
- data/templates/gvc.yml +0 -13
- 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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
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
|
324
|
-
- Uses `
|
325
|
-
-
|
326
|
-
|
327
|
-
|
328
|
-
|
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
|
-
#
|
335
|
-
cpl run -a $APP_NAME --
|
365
|
+
# Runs interactive command, keeps shell open, and stops job when exiting.
|
366
|
+
cpl run -a $APP_NAME --interactive -- rails c
|
336
367
|
|
337
|
-
#
|
338
|
-
cpl run -a $APP_NAME --
|
339
|
-
cpl run -a $APP_NAME -- rails
|
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
|
342
|
-
cpl run -a $APP_NAME -- rails
|
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
|
-
#
|
383
|
-
cpl run
|
397
|
+
# Replaces the existing Dockerfile entrypoint with `bash`.
|
398
|
+
cpl run -a $APP_NAME --entrypoint none -- rails db:migrate
|
384
399
|
|
385
|
-
#
|
386
|
-
cpl run
|
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
|
-
-
|
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/
|
50
|
-
[this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/templates/
|
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
|
-
|
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
|
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
|
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
|
-
-
|
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
|
218
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:reset
|
219
219
|
else
|
220
|
-
cpl run
|
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/
|
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://
|
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
|
-
|
88
|
+
You can do this during the initial app setup, like this:
|
89
89
|
|
90
|
-
1.
|
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`)
|
data/examples/circleci.yml
CHANGED
@@ -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
|
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
|
78
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:reset
|
79
79
|
else
|
80
|
-
cpl run
|
80
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:migrate
|
81
81
|
fi
|
82
82
|
- run:
|
83
83
|
name: Deploy image
|
data/examples/controlplane.yml
CHANGED
@@ -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`, `
|
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
|
28
|
-
|
29
|
-
|
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
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
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 == "
|
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
|
-
|
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
|
-
|
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("
|
130
|
-
.gsub("
|
131
|
-
.gsub("
|
132
|
-
.gsub("
|
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
|